home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1998 August: Tool Chest / Dev.CD Aug 98 TC.toast / Tool Chest / Testing & Debugging / Mac OS Development Toolkit / Automation Essentials 2.3.0 / Host Automation Folder / SPEC Libs / UserInterface.Lib < prev    next >
Encoding:
Text File  |  1998-03-19  |  114.7 KB  |  3,121 lines  |  [TEXT/MPS ]

  1. #
  2. # ****************************************************************************
  3. #
  4. #    File Name:    UserInterface.Lib
  5. #
  6. #    Contains:    Library of tasks that manipulate some aspect of the Human Interface.
  7. #
  8. #    Written by:    KTA, KL, ML, GS et al
  9. #
  10. #    Copyright:    © 1993-1996 by Apple Computer, Inc., all rights reserved.
  11. #
  12. # ****************************************************************************
  13. #            C h a n g e        H i s t o r y (most recent first):
  14. # ****************************************************************************
  15. #
  16. #        Vers      Date        Author        Description
  17. #        ----    --------    ------    ---------------------------------------------
  18. #    2.1.114>      5/3/96    MDF        TypeStr() - Added gSwitchToUSHook task reference.  This will
  19. #                                    support Intl request for switching back to the "U.S." script
  20. #                                    when pTheString contains precomposed doublebyte characters.
  21. #    .1.113+>      5/3/96    MDF        TypeStr() - check for task reference which will switch to "U.S."
  22. #                                    script if InitINTLGlobals() is called in a script.
  23. #    2.1.113>      5/1/96    MDF        Modified CheckYesNo() and TypeList() tasks.
  24. #    .1.112+>      5/1/96    MDF        Modified CheckYesNo() and TypeList() tasks.
  25. #    2.1.112>      2/8/96    JC        Changed all window .r (Rect) traits to .b (bound) traits and
  26. #                                    changed any window insets to reflect new bound rect.
  27. #    2.1.111>      1/2/96    ML        DragAcrossScreens, SizeAcrossScreens - pass         pSpecifier
  28. #                                    into DragWindow call.
  29. #    .1.110+>      1/2/96    ML        DragAcrossScreens, SizeAcrossScreens - pass pSpecifier into
  30. #                                    DragWindow call.
  31. #    2.1.110>    11/21/95    ML        CheckYesNo, DialogDismisser - add support for international
  32. #    2.1.19+>    11/21/95    ML        CheckYesNo, DialogCheck - add support for international
  33. #    <2.1.19>     4/24/95    KTA        Fixed small bugs in DialogDismisser() and TestWindow().
  34. #    <2.1.18>     3/22/95    ML        DialogDismisser() - use _MatchBoolean() to check existence of
  35. #                                    pSpecifier
  36. #    <2.1.17>     2/14/95    KTA        DragAcrossScreen(), SizeAcrossScreen() - Check to see if a
  37. #                                    second monitor exists before matching it.
  38. #    <2.1.16>     2/10/95    KTA        DialogDismisser() - Optimized, removed edittext from
  39. #                                    specifiedDialog / TestWindow() - use _MatchBoolean instead of
  40. #                                    _collect
  41. #    <2.1.15>      2/6/95    ML        CheckYesNo() - use _MatchBoolean instead         of _match
  42. #    <2.1.14>     1/31/95    KTA        Fixed some scrollbar problems in GetVHScrollbars(),
  43. #                                    WindowFunction(), and TestWindow().
  44. #    <2.1.13>     1/19/95    KTA        Changed the name of ExceptionHandler() to ExceptionDispatcher().
  45. #    <2.1.12>     1/10/95    KTA        TestWindow(), ResetWindwow() -  Fixed problem -  weren't
  46. #                                    accounting for the h trait for scroll bars.
  47. #    <2.1.11>     1/10/95    KTA        WindowFunction() - Added new task, resetWindowFunctionList(),
  48. #                                    which removes tests specified by global gDoWindowList
  49. #    <2.1.10>    12/21/94    KTA        DragWindow() - Removed errant {str1}
  50. #     <2.1.9>    12/14/94    ML        Cleaner error handling in Dialogcheck()
  51. #     <2.1.8>    11/28/94    ML        Correct syntax errors
  52. #     <2.1.7>    11/22/94    ML        Added error handling support
  53. #     <2.1.6>     11/8/94    KTA        UnCoverWindow() - Updated so it is possible to pass in
  54. #                                    pFrontWindow.
  55. #     <2.1.5>     9/21/94    KTA        DialogHandler() - Check to see if there was any statictext
  56. #                                    before concatenating strings.
  57. #     <2.1.4>     9/21/94    KTA        ResetWindow() - Fixed trying to reset scrollbars when no
  58. #                                    thumbnail (0,0)
  59. #     <2.1.3>     9/21/94    KTA        Fix syntax error in SelectPopupMenuItem().
  60. #     <2.1.2>     9/20/94    KTA        Comments
  61. #    <2.1.1>         9/20/94        KTA        Added new task - SelectPopUpMenuItem()
  62. #    <2.1.0>         9/20/94        KTA        SelectRadioButton(), SelectCheckBox() - Select by title and
  63. #                                    ordinality instead of just ordinality.
  64. #    2.0.211>      6/9/94    ML        CheckYesNo() - used wildcard for apostrophe in "Don't Save"
  65. #    2.0.210>     5/12/94    KTA        DialogHandler() - Changed the dialog window to either a
  66. #                                    movablemodal or a dialog.
  67. #    <2.0.29>     4/28/94    ML        marked
  68. #    <2.0.28>     4/26/94    KTA        Fixed problem sizing and dragging across multiple monitors.
  69. #    <2.0.27>     4/13/94    KTA        MoveMouse() - variable named wrong.
  70. #    <2.0.26>     3/24/94    KTA        Added new dialogHandler() and DialogDismisser().
  71. #    <2.0.25>     3/16/94    KTA        Fixed bug in MoveRelativeToWindow() when pMouseDown was 1, but
  72. #                                    list of points was passed in.
  73. #    <2.0.24>     3/16/94    KTA        Added new method for MoveRelativeToWindow().
  74. #    <2.0.23>     3/15/94    KTA        Added ordinality to output for UserInterface tasks.
  75. #    <2.0.22>     12/16/93    KTA        SizeWindow() - fixed bug where trying to size window smaller 
  76. #                                    than 20 pixels
  77. #    <2.0.21>     12/2/93    KTA        DialogCheck() - supports button descriptors, TypeStr() added
  78. #                                    gTypeStrOverRide.
  79. #    <2.0.20>    11/19/93    NAGA    modify TCS format
  80. #    <2.0.19>    11/19/93    KTA        A couple of changes for INTL and Performance
  81. #    <2.0.18>    11/11/93    KTA        DialogCheck() - If no pFindStaticText is passed in, it will work
  82. #                                    on any dialog.
  83. #    <2.0.17>     9/22/93    KTA        Removed a projector error message.
  84. #    <2.0.16>     9/22/93    KTA        Changed gEndTimer task references to reflect the task in which
  85. #                                    the references are located.
  86. #    <2.0.15>     9/13/93    KTA        SelectButton(), SelectRadioButton(), selectCheckBox - added
  87. #                                    support for selecting by ordinality.
  88. #    <2.0.14>     9/13/93    KTA        Updated TestLevel specification and DismissDialog() now supports
  89. #                                    KeyEq('.').
  90. #    <2.0.13>      9/9/93    KTA        SelectMenuItem(), KeyEq() - Changed output line so it does not
  91. #                                    say 'About to …'
  92. #    <2.0.12>      9/7/93    KTA        KeyEq() - Added pOtherKey := 3 (controlkey).
  93. #    <2.0.11>      9/1/93    KTA        Parameter Updates
  94. #    <2.0.10>      9/1/93    KTA        More header updates - Window section
  95. #     <2.0.9>      9/1/93    KTA        Updated task headers and parameters.
  96. #     <2.0.8>     8/25/93    KTA        Added support for parity checking the TCS stack.
  97. #     <2.0.7>     7/30/93    KTA        Updates to DismissDialog(), DialogHandler(), and DialogCheck(),
  98. #                                    also updated a couple of descriptors that were still contained
  99. #                                    within lists.
  100. #     <2.0.6>     7/23/93    KTA        CloseWindow() - needed a wait(2) and call IsStandardFile().
  101. #     <2.0.5>     7/22/93    KTA        FindWindow() - if specifier is a descriptor needed a Dammit
  102. #                                    operator (!)
  103. #     <2.0.4>     7/20/93    KTA        A couple of more changes to support FindWindow().
  104. #     <2.0.3>     7/19/93    KTA        Updated for FindWindow to handle descriptors.
  105. #     <2.0.2>      7/7/93    KTA        Changed DismissDialog() so it would properly verify whether
  106. #                                    dialog was dismissed.
  107. #     <2.0.1>      7/6/93    KTA        Performance support and other misc. changes.
  108. #        <1+>     5/21/93    NAGA    Adding header and porting old files to follow new standards
  109. #
  110. # ****************************************************************************
  111. #
  112.  
  113.  
  114. ########################################################################
  115. #                            External libraries 
  116. #=======================================================================
  117. Libraries "Geometry.lib","String.Lib","Output.lib","TCS.lib", "StandardFile.lib",
  118. "ExceptionHandling.Lib";
  119.  
  120.  
  121. #=======================================================================
  122. # Menu related tasks:
  123. #=======================================================================
  124.  
  125. ########################################################################
  126. #                 SelectMenuItem(pMenu1, pMenu2, pMenu3)                    
  127. #=======================================================================
  128. # Author:           KTA
  129. # Description:        Selects the menu item by its title or ordinality.
  130. #                    All parameters are expected to be the same type.
  131. # Parameters:        pMenu1 := Menu item to be selected.
  132. #                    pMenu2 := Menu name if non-hier menu and
  133. #                                 Level 2 menu item if hier menu.
  134. #                    pMenu3 := "" if non-hier menu.
  135. #                                 Menu name if hier menu.
  136. # Returns:            menuTitle - MenuItem name that selection was successful
  137. #                    0 - Couldn't select menu item
  138. # Notes:            It is not mandatory to specify input parameters 'pMenu2' 
  139. #                    or 'pMenu3'.  In that case, default value, "",
  140. #                    will be used.
  141. #=======================================================================
  142. # History:
  143. # KTA    7/6/93        Performance support: Call (gBeginTimer);
  144. # KTA    7/6/93        Readded regularExpression support
  145. # KTA    9/9/93        Changed output line so it does not say 'About to …'
  146. # KTA    9/21/93        Changed gBeginTimer to gPreSelectMenuItemHook, gPostSelectMenuItemHook
  147. # KTA    3/15/94        Added outputting the menuitem ordinality.
  148. # ML    11/22/94    Added error handling support
  149. ########################################################################
  150. TASK SelectMenuItem(pMenu1, pMenu2 := "", pMenu3 := "") 
  151. begin
  152.     returnVal := 0;
  153.     #println "SelectMenuitem∂( ",pMenu1,',',pMenu2,',',pMenu3,"∂)";
  154.     if not (_matchBoolean ([window o:1 s:Dialog c:0 g:0 z:0]))
  155.     begin
  156.         if ((Typeof(pMenu1) = 'string') or (Typeof(pMenu1) = 'regularExpression'))
  157.         begin
  158.             if (pMenu3 = "")                    # Match non-hier menus            
  159.                 ourMenuItem := _match ([menuItem t: pMenu1 m:[menu t: pMenu2]]);
  160.             else                        # Match hier menus                
  161.                 ourMenuItem :=_match ([menuItem t:pMenu1 
  162.                                               m:[menuitem t:pMenu2 
  163.                                               m:[menu t:pMenu3]]]);
  164.         end;
  165.         else
  166.         begin
  167.             if not(pMenu3)                    # Match non-hier menus            
  168.                 ourMenuItem := _match ([menuItem o:pMenu1 m:[menu o:pMenu2]]);
  169.             else                        # Match hier menus                
  170.                 ourMenuItem := _match ([menuItem o:pMenu1 
  171.                                               m:[menuitem o:pMenu2 
  172.                                               m:[menu o:pMenu3]]]);
  173.         end;
  174.     
  175.         if (ourMenuItem)             # Not there
  176.         begin
  177.             menuTitle := ourMenuItem.t;
  178.             menuOrd := ourMenuItem.o;
  179.             if (ourMenuItem.e)         #  enabled
  180.             begin
  181.                 LogStr("Selecting the '{menuTitle}' menu item (ordinality '{menuOrd}')");
  182.                 if (global gMacstiming) and (global gPreSelectMenuItemHook)
  183.                 # possible changes to collect macstime data accurately
  184.                 # after the menu item is selcted Finder doesn't get time so the AppleEvent
  185.                 # can be parsed and executed by the MacsTime CDEV - So we need to start
  186.                 # MacsTime before the menu select
  187.                     Call (gPreSelectMenuItemHook);
  188.                 
  189.                 _select (ourMenuItem,1);
  190.                     
  191.                 if not(gMacsTiming) and (global gPostSelectMenuItemHook)
  192.                     Call (gPostSelectMenuItemHook);
  193.             
  194.                 returnVal := menuTitle;
  195.             end;
  196.             else 
  197.             begin
  198.                 LogStr("!@#$% Menu item '{menuTitle}' (ordinality '{menuOrd}') is not enabled to select.");
  199.             end;
  200.         end;
  201.         else 
  202.             LogStr("!@#$% Could not find menu item '{pMenu1}' to select");
  203.     end;
  204.     else
  205.     begin
  206.         LogStr("!@#$% Dialog present can't select menuItems");
  207.         DialogCheck(, 1);        # Attempt to dismiss the dialog
  208.     end;
  209.         
  210.     return(returnVal);
  211. end; # SelectMenuItem()
  212.  
  213. ########################################################################
  214. #                 SelectPopUpMenuItem(pPopUpMenuItemSpecifer, pPopupMenuSpecifier)                    
  215. #=======================================================================
  216. # Author:           KTA
  217. # Description:        Selects the popUp menu item <pPopUpMenuItemSpecifer>
  218. #                    contained in the popUp menu <pPopupMenuSpecifier>.
  219. #                    Parameter types can be mixed.
  220. # Parameters:        pPopUpMenuItemSpecifer := PopUp menu item to be selected.
  221. #                                        Can be string, integer, descriptor
  222. #                    pPopupMenuSpecifier := PopUp menu which contains <pPopUpMenuItemSpecifer>.
  223. #                                        Can be string, integer, descriptor
  224. # Returns:            1 - successful
  225. #                    0 - Couldn't select menu item
  226. # Notes:            Only works with Popup menuitems that VU recognizes.
  227. #=======================================================================
  228. # History:
  229. # KTA    9/20/94        Created
  230. # ML    11/22/94    Added error handling support
  231. ########################################################################
  232. TASK SelectPopUpMenuItem(pPopUpMenuItemSpecifer, pPopupMenuSpecifier)
  233. begin
  234.     returnVal := 0;
  235.     MenuSpecifierType := Typeof(pPopupMenuSpecifier);
  236.     MenuItemSpecifierType := Typeof(pPopUpMenuItemSpecifer);
  237.     
  238.     if (MenuItemSpecifierType = 'string') and (MenuSpecifierType = 'string')
  239.         thePopup := _match ([menuItem t:pPopUpMenuItemSpecifer m:[ popup t:pPopupMenuSpecifier]]);
  240.     else if (MenuItemSpecifierType = 'string') and (MenuSpecifierType = 'integer')
  241.         thePopup := _match ([menuItem t:pPopUpMenuItemSpecifer m:[ popup o:pPopupMenuSpecifier]]);
  242.     else if (MenuItemSpecifierType = 'integer') and (MenuSpecifierType = 'string')
  243.         thePopup := _match ([menuItem o:pPopUpMenuItemSpecifer m:[ popup t:pPopupMenuSpecifier]]);
  244.     else if(MenuItemSpecifierType = 'integer') and (MenuSpecifierType = 'integer')
  245.         thePopup := _match ([menuItem o:pPopUpMenuItemSpecifer m:[ popup o:pPopupMenuSpecifier]]);
  246.     else if(MenuItemSpecifierType = 'descriptor')
  247.         thePopup := _match ( pPopUpMenuItemSpecifer);
  248.     else if(MenuSpecifierType = 'descriptor')
  249.         thePopup := _match ( pPopupMenuSpecifier);
  250.         
  251.     if(thePopup)
  252.     begin
  253.         if(thePopup.e)
  254.         begin
  255.             PopUPMenuTitle := thepopup.m.t;
  256.             PopUPMenuOrd := thepopup.m.o;
  257.             PopUPItemTitle := thePopup.t;
  258.             PopUPItemOrd := thePopup.o;
  259.             
  260.             _select (thePopup);
  261.             LogStr( "Selecting popup menuitem titled '{PopUPItemTitle}' (ordinality '{PopUPItemOrd}') from popup menu '{PopUPMenuTitle}' ord '{PopUPMenuOrd}'");
  262.             returnVal := 1;
  263.         end;
  264.         else
  265.             LogStr("!@#$% PopUp menu item '{PopUPItemTitle}' (ordinality '{PopUPItemOrd}') in  popup menu '{PopUPMenuTitle}' (ord '{PopUPMenuOrd}') is not enabled to select.");
  266.     end;
  267.     else 
  268.         LogStr("!@#$% Could not find popupmenu item '{pPopUpMenuItemSpecifer}' to select from '{pPopupMenuSpecifier}' popup menu");
  269.  
  270.     return(returnVal);
  271. end;
  272.  
  273. #########################################################################
  274. #                             FindMenu(pTheMenuItem)
  275. #=======================================================================
  276. # Author:              KTA
  277. # Description:        Returns the Menu(s) in which <pTheMenuItem> is contained.
  278. # Parameters:        pTheMenuItem    :=    Title of the menuitem to be searched for.
  279. # Returns:            0    -    Can't match <pTheMenuItem>.
  280. #                    {theMenu,""}    -    for a nonHierarchical menu.
  281. #                    {theHMenuItem, theMenu}    -    if its hierarchical.
  282. # Example:            MyMenu := FindMenu('Paste');
  283. #=======================================================================
  284. # History:
  285. # ML    11/22/94    Added error handling support
  286. #########################################################################
  287. TASK FindMenu(pTheMenuItem)
  288. begin
  289.     MenuName := _match ([menuitem t:pTheMenuItem]);
  290.     if (MenuName)
  291.     begin
  292.         IsMenu := descType(MenuName.m);
  293.         if (IsMenu = 'menu')
  294.         begin
  295.             theMenu := MenuName.m.t;
  296.             Return({theMenu,""});
  297.         end;
  298.         else If (IsMenu = 'menuItem')
  299.         begin
  300.             theHMenuItem := MenuName.m.t;
  301.             try match [menuItem t:pTheMenuItem 
  302.                                               m:[menuitem t:theHMenuItem 
  303.                                                              m:[menu t:?theMenu]]];
  304.             catch theError
  305.                 ExceptionDispatcher(theError);
  306.                 
  307.             Return({theHMenuItem, theMenu});
  308.         end;
  309.     end;
  310.     else Return(0);
  311. end; # FindMenu()
  312.  
  313. #########################################################################
  314. #                            KeyEq(pKeyEquiv,pOtherkey, pNumTimes)
  315. #========================================================================
  316. # Author:        KTA
  317. # Description:    This routine will select the Keyboard Equiv <pKeyEquiv>
  318. # Parameters:    pKeyEquiv -    string holding character to be typed with
  319. #                            command key down.
  320. #                pOtherkey -    integer -  representing special keys to hold 
  321. #                            down in conjunction with the command key
  322. #                    1 - Shift key
  323. #                    2 - Option key
  324. #                    3 - Control key
  325. #                pNumTimes -    integer - representing number of times to type keyEq.
  326. # Returns:        None
  327. # Examples:        KeyEq("q");
  328. #========================================================================
  329. # History:
  330. # KTA    7/2/93        Added pNumTimes parameter for number of times to type KeyEq.
  331. # KTA    7/6/93        Performance support: Call (gBeginTimer);
  332. # KTA    9/7/93        Added pOtherKey := 3 (controlkey)
  333. # KTA    9/9/93        Changed output line so it does not say 'About to …'
  334. # KTA    9/21/93        Changed gBeginTimer to gPreKeyEqHook
  335. # ML    11/22/94    Added error handling support
  336. #########################################################################
  337. TASK KeyEq(pKeyEquiv, pOtherkey := 0, pNumTimes := 1) 
  338. begin
  339.     KeyList := { '',''};
  340.     if (pOtherkey =1) 
  341.         KeyList := {ShiftKey,'-Shift'};
  342.     else if (pOtherkey = 2) 
  343.         KeyList := {Optionkey,'-Option'};
  344.     else if (pOtherkey = 3) 
  345.         KeyList := {Controlkey,'-Control'};
  346.  
  347.     WhichKey := KeyList[2];
  348.     LogStr("Pressing the ∂('{pKeyEquiv}'∂) key and the Command{WhichKey} key {pNumTimes} times");
  349.     
  350.     _pressKey ({ commandKey,KeyList[1]});
  351.     For i := 1 to pNumTimes
  352.     begin
  353.         if (global gPreKeyEqHook)
  354.             Call (gPreKeyEqHook);
  355.         _type ({ pKeyEquiv });
  356.     end;
  357.  
  358.     _releaseKey ({ commandKey,KeyList[1] });
  359. end; # KeyEq()
  360.  
  361.  
  362. #=======================================================================
  363. # Window related tasks:
  364. #=======================================================================
  365. # Description:    This section contains VU code for running tests on the
  366. #                basic controls of a window.
  367. #
  368. #            *** The main task in this section is TestWindow().  It is used to
  369. #                perform a number of window test automatically.
  370. #
  371. #                The window related tasks in this library are grouped in the
  372. #                following logical order:
  373. #
  374. #                TestWindow(pSpecifier, pFunctionList, pRestoreWindow, pNumTimes, pDragXY) 
  375. #                WindowFunction(pSpecifier, pTheFunction, pDragXY, pDestinationPoint) 
  376. #                DragAcrossScreens(pSpecifier,pDragXY) 
  377. #                SizeAcrossScreens(pSpecifier, pDragXY) 
  378. #                AdjustRectToScreen(pTheRect) 
  379. #                CoverCompletely (pFirstWindow, pSecondWindow)
  380. #                ResetWindow(pTheWindow) 
  381. #                SelectWindow(pSpecifier) 
  382. #                UnCoverWindow(pSpecifier, pFrontWindow)
  383. #                DragWindow(pHorizontalPixels, pVerticalPixels, pSpecifier,pAbsolutely) 
  384. #                SizeWindow(pPixelsWide, pPixelsHigh, pSpecifier, pAbsolutely) 
  385. #                ZoomWindow(pSpecifier) 
  386. #                CloseWindow(pHowClose,pOverWrite,pSpecifier,pNewDocName) 
  387. #                ScrollWindow(pWhichScrollBar,pDesirePosition,pMaxPosition) 
  388. #                GetVHScrollBars()
  389. #                CloseAllWindows()
  390. #                FindWindow(pSpecifier) 
  391. #                GetRandomPointsRelativeToWindow(pInset, pSpecifier, pNumPts)
  392. #
  393. #
  394. #
  395. #
  396. #
  397. #
  398. #
  399. #     Copyright Apple Computer, Inc. 1985-1990
  400. #    All rights reserved
  401. #
  402. #========================================================================
  403. # History:
  404. #
  405. #########################################################################
  406.  
  407.  
  408. #########################################################################
  409. #     TestWindow(pSpecifier,pFunctionList,pRestoreWindow,pNumTimes,pDragXY)
  410. #=======================================================================
  411. # Author:         NJV
  412. #
  413. # Description:    Performs the specified functions as defined in the input
  414. #                parameter pFunctionList.  If pFunctionList is not passed,
  415. #                or is passed as 0, then the following operations are
  416. #                performed on the window specified by input parameter
  417. #                pSpecifier.  The default behavior will perform the
  418. #                following behaviors on the frontmost window* (see *NOTE).
  419. #                Listed below is the list of function numbers and a brief
  420. #                description of what that particular function does:
  421. #
  422. #                    #0    Complete Window Test
  423. #                            Performs functions 1 through 17
  424. #                            (17 is done twice - zoom & zoom back)
  425. #                    #1    Resize to random width and height.
  426. #                    #2    Attempt resize to 20,20 (should not allow it)
  427. #                    #3    Scroll the vertical scroll bar to random location.
  428. #                    #4    Scroll the vertical scroll bar to end location.
  429. #                    #5    Scroll the vertical scroll bar to beginning location.
  430. #                    #6    Scroll the vertical scroll bar to original location.
  431. #                    #7    Scroll the horizontal scroll bar to random location.
  432. #                    #8    Scroll the horizontal scroll bar to end location.
  433. #                    #9    Scroll the horizontal scroll bar to beginning location.
  434. #                    #10    Scroll the horizontal scroll bar to original location.
  435. #                    #11    Resize window to largest possible and then
  436. #                    #12    Resize back to smallest window size
  437. #                    #13 Size window across screen border to second screen
  438. #                        (if 2 screens) and back
  439. #                    #14    Drag window across screen border and back
  440. #                    #15    Drag random location and back to original location
  441. #                    #16    Drag window back to original location.
  442. #                    #17    Zoom.
  443. #                    #18 Complete Window Size Test
  444. #                            Performs functions 1,2,11,12, and 13
  445. #                    #19 Complete Window Scroll Test
  446. #                            Performs functions 3,4,5,6,7,8,9, and 10
  447. #                    #20 Complete Window Drag Test
  448. #                            Performs functions 14,15, and 16
  449. #                    #21 Complete Window Zoom Test
  450. #                            Performs function 17 twice (zoom - zoom back)
  451. #                    #22 A More Complete Window Scroll Test
  452. #                            Performs functions 2,3,4,5,6,7,8,9, and 10.
  453. #                            This is the same as #19 except it sizes the
  454. #                            window to the smallest possible size.  This
  455. #                            is better in that it is more likely for the
  456. #                            scrollbars to be active.
  457. #                    #23 A More Complete Window Drag Test
  458. #                            Performs functions 2,14,15, and 16
  459. #                            This is the same as #20 except it sizes the
  460. #                            window to the smallest possible size.  This
  461. #                            is better in that it is more likely for the
  462. #                            window to be able to be dragged across screen
  463. #                            boundaries.
  464. #        
  465. # Parameters: pSpecifier -  Title or Ordinality or partial window descriptor
  466. #                            of window to be tested
  467. #                            If this parameter is not passed, default
  468. #                            behavior of Tasks will be used (generally the
  469. #                            frontmost window - see *NOTE below)
  470. #
  471. #            pFunctionList - A list containing the functions to be
  472. #                            executed and the number of times to exercize
  473. #                            each function.  The functions will be executed
  474. #                            in the order that they are defined.  The default
  475. #                            is to execute all tests once. The pFunctionList
  476. #                            parameter can have the following formats:
  477. #                            
  478. #                            integer:
  479. #                                    Number of a single test to run once.
  480. #                                    Functions are numbered above.
  481. #                                    0 to execute full sequence once.
  482. #
  483. #                            list of integers:
  484. #                                    A list of test numbers to run -
  485. #                                    each test will be run once and
  486. #                                    in the same order that they appear
  487. #                                    in the list.
  488. #
  489. #                            list of lists:
  490. #                                    A list of {test#,#times} lists
  491. #                                    where test# is the number of the
  492. #                                    test and #times is the number of
  493. #                                    times to execute that test.  Each
  494. #                                    list will be processed in order.
  495. #                                    If an item in the main list is an
  496. #                                    integer and not a list, that test
  497. #                                    number will be executed once.
  498. #
  499. #                pRestoreWindow -    1 to restore window to original size,
  500. #                                    location, and scrollbar status.
  501. #                                0 not to restore window
  502. #
  503. #                pNumTimes -    integer for number of times to execute test
  504. #
  505. #                pDragXY -    Upper Left-Top corner to drag window to
  506. #
  507. # Returns:        0 - Couldn't find specified window
  508. #                1 - Executed OK
  509. #
  510. # Assumptions:    None
  511. #
  512. #========================================================================
  513. # History:
  514. # KTA    1/10/95  Added resetWindowFunctionList() which removes tests is
  515. #                    specified by global gDoWindowList
  516. # KTA    1/10/95  Fixed problem -  weren't accounting for the h trait for scroll bars.
  517. # KTA    1/31/95  Fixed problem -  should have been the e trait not the h trait
  518. # ML    2/6/95    _MatchBoolean instead of _collect to first check for scrollbars
  519. # KTA    2/24/95  hScroll and vScroll were assigned to the wrong trait (thnx Mona)
  520. # JC    2/6/96      Changed all window .r (Rect) traits to .b (bound) traits.
  521. #########################################################################
  522. TASK TestWindow(pSpecifier := 0, pFunctionList := 0, pRestoreWindow := 0, pNumTimes := 1, pDragXY := {0,20}) 
  523. begin
  524.     if (global gScreenInset)
  525.         pDragXY := {gScreenInset[1], gScreenInset[2]};
  526.     global gOrigScrollBars := 0;    # default to scrollbars at beginning
  527.     returnVal := 0;
  528.  
  529.     # get the window's original status - if we can't find it, return 0
  530.     originalWindowDesc := FindWindow(pSpecifier);
  531.     if (originalWindowDesc)
  532.     begin
  533.         
  534.         # set all original window variable information
  535.         originalOrd := originalWindowDesc.o;
  536.         if (originalOrd <> 1)
  537.             originalWindowDesc := SelectWindow(pSpecifier);
  538.         originalOrd := originalWindowDesc.o;
  539.         theTitle := originalWindowDesc.t;
  540.         oldRect := originalWindowDesc.b;
  541.         theDesc := [window t:theTitle o:originalOrd];    # Partial window descriptor
  542.         
  543.         # and scroll bar positions
  544.         if (_matchBoolean ([scrollbar w:[window t:theTitle o:originalOrd]]!))
  545.         begin
  546.             ScrollBars := _collect ([scrollbar w:[window t:theTitle o:originalOrd]]!,1);
  547.             if (card ScrollBars >= 2) begin
  548.                 hscroll := ScrollBars[1];
  549.                 vscroll := ScrollBars[2];
  550.             end;
  551.             else if (card ScrollBars = 1)
  552.             begin
  553.                 hscroll := ScrollBars[1];
  554.                 vscroll := [scrollBar s:{ 0, 0 } e:false];
  555.             end;
  556.             
  557.             if (hscroll.e) and not(hscroll.s = { 0, 0 })
  558.                 horizontalscroll := hscroll.s;
  559.             
  560.             if (vscroll.e) and not(vscroll.s = { 0, 0 })
  561.                 Verticalscroll := vscroll.s;
  562.                 
  563.             if(horizontalscroll) or (Verticalscroll)
  564.             begin
  565.                 if(horizontalscroll) and (Verticalscroll)
  566.                     gOrigScrollBars := {Verticalscroll,horizontalscroll};
  567.                 else if (Verticalscroll)
  568.                     gOrigScrollBars := {Verticalscroll,0};
  569.                 else if (horizontalscroll)
  570.                     gOrigScrollBars := {0, horizontalscroll};
  571.             end;
  572.             else
  573.                 gOrigScrollBars := 0;
  574.         end;        
  575.  
  576.         # if pFunctionList = 0, run default behavior
  577.         if (pFunctionList = 0) begin
  578.             println;
  579.             println "===========================================================================";
  580.             LogStr("Starting Complete Window Test...");
  581.             #pFunctionList := {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,17};
  582.             pFunctionList := {17,17,12,11,1,3,4,5,6,7,8,9,10,13,14,15,11};
  583.         end;
  584.  
  585.         # first, drag the window onto screen to assure more success at functions
  586.         # Drag it to the desired location (if needed)
  587.         if not ((tempRect[1] = pDragXY[1]) and (tempRect[2] = pDragXY[2]))
  588.             if global gDoWindowList[3] # if dragging is available
  589.                 DragWindow(pDragXY[1],pDragXY[2],theDesc,1);    # Call with partial window descriptor
  590.         
  591.         #Remove any tests which are not supposed to run according to the global gDoWindowList
  592.         pFunctionList := resetWindowFunctionList(pFunctionList); 
  593.  
  594.         for iterationNum := 1 to pNumTimes do begin
  595.             # Now perform our test(s)
  596.             if (TypeOf(pFunctionList) = "integer") begin    # it's a single test
  597.                 WindowFunction(theDesc, pFunctionList, pDragXY, oldRect);
  598.             end;
  599.             else begin    # it's a list of tests
  600.                 for currentFunction := 1 to card pFunctionList do begin
  601.                     theFunction := pFunctionList[currentFunction];
  602.                     if (TypeOf(theFunction) = "list") begin
  603.                         for tempCount := 1 to theFunction[2] begin
  604.                             if (WindowFunction(theDesc,theFunction[1],pDragXY,oldRect))
  605.                                 returnVal := 1;    
  606.                         end;
  607.                     end;
  608.                     else begin
  609.                         if (WindowFunction(theDesc,theFunction,pDragXY,oldRect))
  610.                             returnVal := 1;    
  611.                     end;
  612.                 end;
  613.             end;
  614.         end;
  615.         
  616.         if (pRestoreWindow)
  617.             ResetWindow(originalWindowDesc);
  618.         
  619.         returnVal := 1;
  620.     end;
  621.     else
  622.         LogStr("Couldn't find specified window for TestWindow");
  623.     
  624.     return(returnVal);
  625. end; # TestWindow()
  626.  
  627.  
  628. #########################################################################
  629. #         WindowFunction(pSpecifier, pTheFunction, pDragXY,pDestinationPoint)
  630. #=======================================================================
  631. # Author:         NJV
  632. # Description:    Performs the specified function defined in the input
  633. #                parameter pTheFunction to the window specified by pSpecifier.
  634. #                Listed below is the list of function numbers and a brief
  635. #                description of what that particular function does:
  636. #
  637. #                    #1    Resize to random width and height.
  638. #                    #2    Attempt resize to 20,20 (should not allow it)
  639. #                    #3    Scroll the vertical scroll bar to random location.
  640. #                    #4    Scroll the vertical scroll bar to end location.
  641. #                    #5    Scroll the vertical scroll bar to beginning location.
  642. #                    #6    Scroll the vertical scroll bar to original location.
  643. #                    #7    Scroll the horizontal scroll bar to random location.
  644. #                    #8    Scroll the horizontal scroll bar to end location.
  645. #                    #9    Scroll the horizontal scroll bar to beginning location.
  646. #                    #10    Scroll the horizontal scroll bar to original location.
  647. #                    #11    Resize window to largest possible
  648. #                    #12    Resize back to smallest window size
  649. #                    #13 Size window across screen border to second screen
  650. #                        (if 2 screens) and back
  651. #                    #14    Drag window across screen border and back
  652. #                    #15    Drag window to random location.
  653. #                    #16    Drag window to location specified by pDestinationPoint.
  654. #                    #17    Zoom.
  655. #                    #18 Complete Window Size Test
  656. #                            Performs functions 1,2,11,12, and 13
  657. #                    #19 Complete Window Scroll Test
  658. #                            Performs functions 3,4,5,6,7,8,9, and 10
  659. #                    #20 Complete Window Drag Test
  660. #                            Performs functions 14,15, and 16
  661. #                    #21 Complete Window Zoom Test
  662. #                            Performs function 17 twice (zoom - zoom back)
  663. #                    #22 A More Complete Window Scroll Test
  664. #                            Performs functions 2,3,4,5,6,7,8,9, and 10
  665. #                            This is the same as #19 except it sizes the
  666. #                            window to the smallest possible size.  This
  667. #                            is better in that it is more likely for the
  668. #                            scrollbars to be active.
  669. #                    #23 A More Complete Window Drag Test
  670. #                            Performs functions 2,14,15, and 16
  671. #                            This is the same as #20 except it sizes the
  672. #                            window to the smallest possible size.  This
  673. #                            is better in that it is more likely for the
  674. #                            window to be able to be dragged across screen
  675. #                            boundaries.
  676. #
  677. # Parameters:    pSpecifier -    Title of window to be tested
  678. #
  679. #                pTheFunction -    The number of the test to run
  680. #
  681. #                pDragXY -    Left-Top point (list of {left,top}) to drag
  682. #                            window to. (used if pTheFunction = 13 or 14)
  683. #    
  684. #                pDestinationPoint -    Left/Top point (list of {left,top}) of
  685. #                                    original window (used if pTheFunction = 16)
  686. #
  687. # Returns:        0 - Couldn't perform specified Task
  688. #                1 - Executed OK
  689. #
  690. # Assumptions:    None.
  691. #
  692. # *NOTE:        The TestWindow() function provides much more versatility
  693. #                than this routine.  WindowFunction is called by TestWindow.
  694. #========================================================================
  695. # History:
  696. # ML    11/22/94    Added error handling support
  697. # KTA    1/10/95     Added resetWindowFunctionList() which removes tests is
  698. #                    specified by global gDoWindowList
  699. # KTA    1/31/95     Check scrollbars to ensure they are enabled before scrolling
  700. # JC    2/6/96      Changed all window .r (Rect) traits to .b (bound) traits.
  701. # JC    2/6/96      Changed "inset := { 0,20,0,0};" to "inset := { 0,0,0,0};".
  702. #########################################################################
  703. TASK WindowFunction(pSpecifier, pTheFunction, pDragXY, pDestinationPoint) 
  704. begin
  705.     if (global gScreenInset)
  706.         inset := gScreenInset;
  707.     else
  708.         inset := { 0,0,0,0};  ##use to be inset := { 0,20,0,0};
  709.     # if the user wants a multiple function (#18-#23), set FunctionList
  710.     # accordingly
  711.     if ((pTheFunction >= 18) and (pTheFunction <= 23)) begin
  712.         
  713.         # reset FunctionList
  714.         if (pTheFunction = 18) begin
  715.             println;
  716.             println "===========================================================================";
  717.             LogStr("Starting Complete Window Size Test...");
  718.             FunctionList := {1,2,11,12,13};
  719.         end;
  720.         else if (pTheFunction = 19) begin
  721.             println;
  722.             println "===========================================================================";
  723.             LogStr("Starting Complete Window Scroll Test...");
  724.             FunctionList := {3,4,5,6,7,8,9,10};
  725.         end;
  726.         else if (pTheFunction = 20) begin
  727.             println;
  728.             println "===========================================================================";
  729.             LogStr("Starting Complete Window Drag Test...");
  730.             FunctionList := {14,15,16};
  731.         end;
  732.         else if (pTheFunction = 21) begin
  733.             println;
  734.             println "===========================================================================";
  735.             LogStr("Starting Complete Window Zoom Test...");
  736.             FunctionList := {17,17};
  737.         end;
  738.         else if (pTheFunction = 22) begin
  739.             println;
  740.             println "===========================================================================";
  741.             LogStr("Starting Complete Window Scroll Test - Will Shrink Window First...");
  742.             FunctionList := {2,3,4,5,6,7,8,9,10};
  743.         end;
  744.         else if (pTheFunction = 23) begin
  745.             println;
  746.             println "===========================================================================";
  747.             LogStr("Starting Complete Window Drag Test - Will Shrink Window First...");
  748.             FunctionList := {2,14,15,16};
  749.         end;
  750.             
  751.         #Remove any tests which are not supposed to run according to the global gDoWindowList
  752.         FunctionList := resetWindowFunctionList(FunctionList); 
  753.                                                                 
  754.         # now execute each test using recursion
  755.         noError := 1;    # no errors yet
  756.         for each item in FunctionList begin
  757.             if not (WindowFunction(pSpecifier,item,pDragXY,pDestinationPoint))
  758.                 foundError := 1;
  759.         end;
  760.         return(foundError);
  761.     end;
  762.  
  763.     if (pTheFunction = 1)                                #1    Resize to random width and height.
  764.         return(SizeWindow('random','random',pSpecifier));                            
  765.     
  766.     else if (pTheFunction = 2)                            #2    Attempt resize to 20,20 (should not allow it)
  767.         return(SizeWindow(20,20,pSpecifier));                                        
  768.     
  769.     else if ((pTheFunction >= 3) and (pTheFunction <= 10)) begin
  770.         # get the old value of the scroll bars to replace scrollbars as they were found.
  771.         theScrollBars := GetVHScrollBars();
  772.         vertical := theScrollBars[1];
  773.         horizontal := theScrollBars[2];
  774.         oldVertical := vertical.s;
  775.         oldHorizontal := horizontal.s;
  776.         
  777.         if (pTheFunction = 3) and (vertical.e)             #3    Scroll the vertical scroll bar to random location.
  778.             return(ScrollWindow('V'));                                            
  779.  
  780.         else if (pTheFunction = 4) and (vertical.e)     #4    Scroll the vertical scroll bar to end location.
  781.             return(ScrollWindow('V',1,1));                                        
  782.         
  783.         else if (pTheFunction = 5) and (vertical.e)     #5    Scroll the vertical scroll bar to beginning location.
  784.             return(ScrollWindow('V',0,1));                                        
  785.         
  786.         else if (pTheFunction = 6) and (vertical.e)     #6    Scroll the vertical scroll bar to original location.
  787.             return(ScrollWindow('V',oldVertical[1],oldVertical[2]));            
  788.             
  789.         else if (pTheFunction = 7) and (horizontal.e)     #7    Scroll the horizontal scroll bar to random location.
  790.             return(ScrollWindow('H'));                                            
  791.         
  792.         else if (pTheFunction = 8) and (horizontal.e)     #8    Scroll the horizontal scroll bar to end location.
  793.             return(ScrollWindow('H',1,1));                                        
  794.         
  795.         else if (pTheFunction = 9) and (horizontal.e)     #9    Scroll the horizontal scroll bar to beginning location.
  796.             return(ScrollWindow('H',0,1));                                        
  797.         
  798.         else if(horizontal.e)                            #10    Scroll the horizontal scroll bar to original location.
  799.             return(ScrollWindow('H',oldHorizontal[1],oldHorizontal[2]));        
  800.     end;
  801.     
  802.     else if (pTheFunction = 11) begin                    #11    Resize window to largest possible
  803.         # Match to get new rect
  804.         theWind := FindWindow(pSpecifier);
  805.         if not (theWind)
  806.             return(0);
  807.         else
  808.             newRect := theWind.b;
  809.         # get screen coordinates
  810.         try match [screen r:?theScreenRect m:true]!;
  811.         catch theError
  812.             ExceptionDispatcher(theError);
  813.         
  814.         #11    Resize window to largest possible
  815.         return(SizeWindow(theScreenRect[3]-newRect[1]-inset[3],theScreenRect[4]-newRect[2]-inset[4],pSpecifier));    #11
  816.     end;
  817.     
  818.     else if (pTheFunction = 12)    #12    Resize to smallest window size
  819.         return(SizeWindow(20,20,pSpecifier));                                            #12
  820.     
  821.     else if (pTheFunction = 13)    #13 Size window across screen border to second screen (if 2 screens) and back
  822.     begin
  823.         origWind := findWindow(pSpecifier);
  824.         theReturn := SizeAcrossScreens(pSpecifier,pDragXY);                                #13
  825.         if(theReturn)
  826.         begin
  827.             DragWindow(origWind.b[1],origWind.b[2],pSpecifier);
  828.             SizeWindow(origWind.b[3]-origWind.b[1],origWind.b[4]-origWind.b[2],pSpecifier);
  829.         end;
  830.         return(theReturn);
  831.     end;
  832.     
  833.     else if (pTheFunction = 14)    #14    Drag window across screen border and back
  834.     begin
  835.         origWind := findWindow(pSpecifier);
  836.         theReturn := DragAcrossScreens(pSpecifier,pDragXY);                                #14
  837.         if(theReturn)
  838.             DragWindow(origWind.b[1],origWind.b[2],pSpecifier);
  839.         return(theReturn);
  840.     end;
  841.     
  842.     else if (pTheFunction = 15)    #15    Drag random location.
  843.         return(DragWindow('RandomReturn','Random',pSpecifier));                            #15
  844.     
  845.     else if (pTheFunction = 16)     #16    Drag window back to original location.
  846.         return(DragWindow(pDestinationPoint[1],pDestinationPoint[2],pSpecifier));        #16
  847.     
  848.     else if (pTheFunction = 17)     #17    Zoom.
  849.         return(ZoomWindow(pSpecifier));                                                    #17
  850.  
  851.     else
  852.         LogStr("!@#$% - scriptor error - Unknown Function Number ∂"{pTheFunction}∂" passed to WindowFunction()");
  853.     return(0);
  854. end;
  855.  
  856. #########################################################################
  857. #                ResetWindowFunctionList(pFunctionList)
  858. #========================================================================
  859. # Author:        KTA    
  860. # Description:    This routine takes a window functionlist as a parameter and removes
  861. #                any test which are specified as not available by the gDoWindowList global.
  862. # Parameters:    pFunctionList - Initial function list
  863. #                global gDoWindowList := {1,1,1,1};
  864. #                 Set each element to 1 or 0.  Flag for performing DoWindows tests as follows:
  865. #                 Element:      1 - Sizing
  866. #                             2 - Scrolling
  867. #                              3 - Dragging
  868. #                             4 - Zooming
  869. # Returns:        Functiuon list after remove tests that aren't supported.
  870. # Examples:        FunctionList := ResetWindowFunctionList({1,2,11,12,16,17});
  871. #========================================================================
  872. # History:
  873. # KTA    1/10/95    Created
  874. #########################################################################
  875. task ResetWindowFunctionList(pFunctionList)
  876. begin
  877.     global gDoWindowList;
  878.  
  879.     if(TypeOf(pFunctionList) = 'integer')
  880.         pFunctionList := {pFunctionList};
  881.         
  882.     WindowTests := {{'Size', 1, {1,2,11,12,13}}, {'Scroll',2,{3,4,5,6,7,8,9,10}}, {'Drag', 3, {14,15,16}}, {'Zoom',4,{17}}};
  883.     for each testType in WindowTests
  884.     begin 
  885.         numItems := Card(pFunctionList);
  886.         newFunctionList := {};
  887.         if not(gDoWindowList[testType[2]])
  888.         begin
  889.             for i := 1 to numItems
  890.             begin
  891.                 if not(isMember(pFunctionList[i], testType[3]))
  892.                 begin
  893.                     thePos := card(newFunctionList)+1;
  894.                     newFunctionList[thePos] := pFunctionList[i];
  895.                 end;
  896.             end;
  897.             pFunctionList := newFunctionList;
  898.             numItems := Card(pFunctionList);
  899.             newFunctionList := {};
  900.         end;
  901.     end;
  902.     return(pFunctionList);    
  903. end;
  904.  
  905.  
  906. #########################################################################
  907. #                    DragAcrossScreens(pSpecifier,pDragXY)
  908. #========================================================================
  909. # Author:            NJV
  910. # Description:        If there are two screens present, this task will drag
  911. #                    the window specified by <pSpecifier> so that half of the
  912. #                    window is on the first screen and half of the window
  913. #                    is on the second screen.  
  914. # Parameters:        pSpecifier - title of window to drag
  915. #                    pDragXY - a list of two co-ordinates (left-top) pixel
  916. #                            to drag window to (i.e.{0,20} to avoid menu bar
  917. #                            on main screen).
  918. # Returns:            1 - successful
  919. #                    0 - unsuccessful
  920. # Examples:            DragAcrossScreens("Untitled",{0,20}).
  921. # Assumptions:        None
  922. #========================================================================
  923. # History:
  924. # KTA    8/24/93        TCS stack parity check
  925. # ML    11/22/94    Added error handling support
  926. # KTA    2/14/95        Check to see if a second monitor exists before matching it.
  927. # ML    1/2/96        pass pSpecifier into DragWindow call
  928. # JC    2/6/96      Changed all window .r (Rect) traits to .b (bound) traits.
  929. #########################################################################
  930. TASK DragAcrossScreens(pSpecifier,pDragXY) 
  931. begin
  932.     returnVal := 0;
  933.     failStr := '';
  934.     # get screen information
  935.     s1 := _match ([screen m:true]!, 1);
  936.     if(_MatchBoolean([screen m:false]))
  937.         s2 := _match ([screen m:false]!, 1);
  938.     wind := FindWindow(pSpecifier);
  939.     
  940.     TCSStart({ 2, global kTCSetUIWindowDrag },"DragAcrossScreens");
  941.     if (s2 and s1 and wind)
  942.     begin
  943.         # get half of the window height and half of the window width
  944.         hWidth := ((wind.b[3] - wind.b[1])/2);
  945.         hHeight := ((wind.b[4] - wind.b[2])/2);
  946.         
  947.         # assign various sides of screens to easier and shorter variables
  948.         l1 := s1.r[1];    r1 := s1.r[3];    t1 := s1.r[2];    b1 := s1.r[4];
  949.         l2 := s2.r[1];    r2 := s2.r[3];    t2 := s2.r[2];    b2 := s2.r[4];
  950.         
  951.         # determine if screen2 is to left or right of main screen
  952.         if ((r2 = l1) or (l2 = r1)) begin
  953.             if (t1 > t2)
  954.                 Dy := t1 + pDragXY[2];
  955.             else
  956.                 Dy := t2;
  957.             if (l1 < l2)
  958.                 Dx := l2 - hWidth;
  959.             else
  960.                 Dx := l1 - hWidth;
  961.         end;
  962.         
  963.         # must be above or below main screen
  964.         else begin
  965.             if (l1 > l2)
  966.                 Dx := l1;
  967.             else
  968.                 Dx := l2;
  969.             if (t1 < t2)
  970.                 Dy := t2 - hHeight;
  971.             else
  972.                 Dy := t1 - hHeight;
  973.         end;
  974.         
  975.         LogStr("Dragging window across screen borders...");
  976.         returnVal :=  DragWindow(Dx,Dy,pSpecifier);
  977.     end;
  978.     else if not (s2)
  979.         failStr := "Note: Cannot drag across screens because the target doesn't have two monitors";
  980.     else
  981.         failStr := "Something not here couldn't DragAcrossScreens";    # - return unsuccessful
  982.         
  983.     if not(returnVal)
  984.         TCSReturn := -1;     # Feature not available
  985.     else
  986.         TCSReturn := 1;
  987.  
  988.     TCSEnd({ 2, global kTCSetUIWindowDrag }, TCSReturn,failStr);
  989.     if(failStr)    
  990.         LogStr(failStr);
  991.     return(returnVal);
  992. end;    # DragAcrossScreens()
  993.  
  994. #########################################################################
  995. #                SizeAcrossScreens(pSpecifier,pDragXY)
  996. #========================================================================
  997. # Author:            NJV
  998. # Description:        If there are two screens present, this task will size
  999. #                    the window specified by <pSpecifier>  (if there's a grow box)
  1000. #                    so half of the window is on the first screen and half of
  1001. #                    the window is on the second screen.  
  1002. # Parameters:        pSpecifier - Descriptor of the window to size.
  1003. #                    pDragXY - a list of two co-ordinates (left-top) pixel
  1004. #                            to drag window to (i.e.{0,20} to avoid menu bar
  1005. #                            on main screen).
  1006. # Returns:            1 - successful
  1007. #                    0 - unsuccessful
  1008. # Examples:            SizeAcrossScreens("myWindow",{0,20}).
  1009. # Assumptions:        None
  1010. #========================================================================
  1011. # History:
  1012. # KTA    8/24/93        TCS stack parity check
  1013. # ML    11/22/94    Added error handling support
  1014. # KTA    2/14/95        Check to see if a second monitor exists before matching it.
  1015. # ML    1/2/96        pass pSpecifier into DragWindow call
  1016. # JC    2/6/96      Changed all window .r (Rect) traits to .b (bound) traits.
  1017. #########################################################################
  1018. TASK SizeAcrossScreens(pSpecifier, pDragXY) 
  1019. begin
  1020.     # BUG - if second screen is above or below main screen, the following error occurs,
  1021.     # but routine still works
  1022.     # size [window … ] w: horizontal coordinate off bounds
  1023.     returnVal := 0;
  1024.     failStr := '';
  1025.     # get screen information
  1026.     s1 := _match ([screen m:true]!, 1);
  1027.     if(_MatchBoolean([screen m:false]))
  1028.         s2 := _match ([screen m:false]!, 1);
  1029.     
  1030.     wind := FindWindow(pSpecifier);
  1031.     
  1032.     TCSStart({ 2, global kTCSetUIWindowSize }, "SizeAcrossScreens");
  1033.     if (s2 and s1 and wind)
  1034.     begin            
  1035.         # determine smallest size of window's width and height
  1036.         SizeWindow(20,20);    # attempt to size to 20,20
  1037.         newWind := FindWindow(pSpecifier);
  1038.         wWidth := newWind.b[3] - newWind.b[1];
  1039.         wHeight := newWind.b[4] - newWind.b[2];
  1040.         
  1041.         # assign various sides of screens to easier and shorter variables
  1042.         l1 := s1.r[1];    r1 := s1.r[3];    t1 := s1.r[2];    b1 := s1.r[4];
  1043.         l2 := s2.r[1];    r2 := s2.r[3];    t2 := s2.r[2];    b2 := s2.r[4];    
  1044.         
  1045.         # determine if screen2 is to left or right of main screen
  1046.         if (r2 = l1) begin        # screen 2 is left of screen 1
  1047.             Dx := l1 - wWidth;    # put on right edge of window on left edge of screen 2
  1048.             
  1049.             # calculate top y value of window
  1050.             if (t2 > t1) begin    # mid or low left - put at b1 level of screen 2
  1051.                 if ((b1 - wHeight) < (t2+wHeight)) begin    # can't be done
  1052.                     LogStr("Screen positions do not allow for sizing across 2 monitors");
  1053.                     return(ResetWindow(wind));
  1054.                 end;
  1055.                 Dy := t2;
  1056.             end;
  1057.             else                # high-left
  1058.                 Dy := b2 - wHeight;
  1059.             Sy := b1-Dy;
  1060.             Sx := wWidth + (r1-l1);
  1061.         end;
  1062.         
  1063.         else if (l2 = r1) begin    # screen 2 is right of screen 1
  1064.             Dx := l2 - wWidth;    # put at right of screen 1
  1065.             if (t2 > t1)        # mid or low right    
  1066.                 Dy := t2 - wHeight;
  1067.             else begin            # high right
  1068.                 if ((b2 - wHeight) < (t1+wHeight)) begin    # can't be done
  1069.                     LogStr("Screen positions do not allow for sizing across 2 monitors");
  1070.                     return(ResetWindow(wind));
  1071.                 end;
  1072.                 Dy := t1 + pDragXY[2];
  1073.             end;
  1074.             Sy := b2-Dy;
  1075.             Sx := wWidth + (r2-l2);
  1076.         end;
  1077.         
  1078.         # must be above or below main screen
  1079.         else begin
  1080.             if (l1 > l2)
  1081.                 Dx := l2;
  1082.             else
  1083.                 Dx := l1;
  1084.             if (t1 < t2) begin        # screen below main screen
  1085.                 Dy := t2 - wHeight;
  1086.                 Sy := b2-t2+wHeight;
  1087.                 Sx := r2 - Dx;
  1088.             end;
  1089.             else begin                # screen above main screen
  1090.                 Dy := t1 - wHeight;
  1091.                 Sy := (b1-t1) + wHeight;
  1092.                 Sx := r1 - Dx;
  1093.             end;
  1094.         end;
  1095.         
  1096.         DragWindow(Dx,Dy,pSpecifier);
  1097.         LogStr("Sizing window across screen borders...");
  1098.         SizeWindow(Sx-1,Sy);
  1099.         returnVal := 1;
  1100.     end;
  1101.     else if not (s2)
  1102.         failStr := "Note: Cannot size across screens because the target doesn't have two monitors";
  1103.     else
  1104.         failStr := "Something not here - couldn't resize across screens";
  1105.  
  1106.     if not(returnVal)
  1107.         TCSReturn := -1;     # Feature not available
  1108.     else
  1109.         TCSReturn := 1;
  1110.  
  1111.     TCSEnd({ 2, global kTCSetUIWindowSize }, TCSReturn,failStr);
  1112.     if(failStr)
  1113.         LogStr(failStr);    
  1114.     return(returnVal);
  1115. end; # SizeAcrossScreens()
  1116.  
  1117.  
  1118. #########################################################################
  1119. #                        AdjustRectToScreen(pTheRect)
  1120. #========================================================================
  1121. # Author:            NJV
  1122. # Description:        This routine checks a rectangle to see if it is within
  1123. #                    the screen, if any part of it is not, it will be 
  1124. #                    clipped so as to fit the screen.  This is done by
  1125. #                    comparing the coordinates of the rectangle with that of 
  1126. #                    the screen.  
  1127. # Parameters:        pTheRect - holds the coordinates of the rectangle.
  1128. # Returns:            pTheRect -     the coordinates of the clipped rectangle.
  1129. #                                (if it was not completely within the screen)
  1130. #                            or    the coordinates of the original rectangle
  1131. #                                (if it lies totally within the screen)
  1132. # Examples:            AdjustRectToScreen(Window.r).
  1133. # Assumptions:        All windows are no larger than the screen.
  1134. #========================================================================
  1135. # History:
  1136. # ML    11/22/94    Added error handling support
  1137. #########################################################################
  1138. TASK AdjustRectToScreen(pTheRect) 
  1139. begin
  1140.     screenList := _collect ([screen]!,1);
  1141.     screenCount := card screenList;
  1142.     if (screenCount = 1) begin                    # only one screen
  1143.         screenRect := screenList[1].r;
  1144.         Top := pTheRect[2];                        # 'Top' cannot go beyond the title bar
  1145.         
  1146.         if (pTheRect[1] <= screenRect[1])         # compare left,top,right and bottom
  1147.             Left := screenRect[1];                # coordinates with screen coordinates
  1148.         else                                
  1149.             Left := pTheRect[1];
  1150.         if (pTheRect[3] >= screenRect[3])
  1151.             Right := screenRect[3];
  1152.         else
  1153.             Right := pTheRect[3];
  1154.         if (pTheRect[4] >= screenRect[4])
  1155.             Bottom := screenRect[4];
  1156.         else
  1157.             Bottom := pTheRect[4]; 
  1158.             
  1159.         pTheRect :=     {Left,Top,Right,Bottom};
  1160.         return(pTheRect);
  1161.     end;
  1162. end;    # AdjustRectToScreen()
  1163.  
  1164.  
  1165.  
  1166. #########################################################################
  1167. #                        CoverCompletely(pFirstWindow,pSecondWindow)
  1168. #========================================================================
  1169. # Author:            SMQ
  1170. # Description:        This routine determines whether or not one window 
  1171. #                    completely covers another.  This is done by comparing
  1172. #                    the coordinates of both windows.  
  1173. # Parameters:        pFirstWindow - specifies the first window.
  1174. #                    pSecondWindow - specifies the second window.
  1175. # Returns:            1 - second window is completely covered by the first.
  1176. #                    0 - second window is partially or totally Uncovered.
  1177. # Examples:            CoverCompletely(window1,window2).
  1178. # Assumptions:        None
  1179. #========================================================================
  1180. # History:
  1181. # JC    2/6/96      Changed all window .r (Rect) traits to .b (bound) traits.
  1182. #########################################################################
  1183. TASK CoverCompletely (pFirstWindow, pSecondWindow)
  1184. begin
  1185.     returnVal := 0 ;
  1186.     
  1187.     firstWindow := FindWindow(pFirstWindow);
  1188.     secondWindow := FindWindow(pSecondWindow);
  1189.     firstOrd := firstWindow.o;
  1190.     firstRect := firstWindow.b;
  1191.     secondOrd := secondWindow.o;
  1192.     secondRect := secondWindow.b;
  1193.     if (firstOrd < secondOrd) begin            # could be covered - let's check
  1194.         # first, adjust the rectangles - if required
  1195.         Rect2 := AdjustRectToScreen(secondRect);
  1196.         Rect1 := AdjustRectToScreen(firstRect);
  1197.         returnVal := RectInRect(Rect2,Rect1);
  1198.     end;
  1199.     return(returnVal);
  1200. end;    # CoverCompletely()
  1201.  
  1202. #########################################################################
  1203. #                        ResetWindow(pTheWindow)
  1204. #========================================================================
  1205. # Author:            NJV
  1206. # Description:        Resets the first window with a grow and zoom box to
  1207. #                    the size and position of the input parameter wind 
  1208. #                    window descriptor.  
  1209. # Parameters:        pTheWindow - window descriptor of original window.
  1210. # Returns:            0 - error
  1211. #                    1 - no error
  1212. # Examples:            ResetWindow(pTheWindow).
  1213. # Assumptions:        None
  1214. #========================================================================
  1215. # History:
  1216. # KTA    9/21/94    Fixed trying to reset scrollbars when no thumbnail (0,0)
  1217. # KTA    1/10/95  Fixed problem -  weren't accounting for the e trait for scroll bars.
  1218. #########################################################################
  1219. TASK ResetWindow(pTheWindow) 
  1220. begin
  1221.     global gOrigScrollBars;
  1222.     returnVal := 0;
  1223.     
  1224.     theWind := SelectWindow([window g:true z:true]!);
  1225.     if (theWind)
  1226.     begin
  1227.         windOrd := theWind.o;
  1228.         theTitle := theWind.t;
  1229.         windRect := theWind.r;
  1230.         theDesc := [window t:theTitle o:windOrd]!;# Partial window descriptor contains TITLE and ORD
  1231.         
  1232.         LogStr("==== Restoring window titled ∂"{theTitle}∂" to original size/location"); 
  1233.         SizeWindow(20,20,theDesc);
  1234.         DragWindow(pTheWindow.r[1],pTheWindow.r[2],theDesc); 
  1235.         SizeWindow(pTheWindow.r[3]-pTheWindow.r[1],pTheWindow.r[4]-pTheWindow.r[2],theDesc);   
  1236.         if ((not isUndefined(gOrigScrollBars)) and (global gOrigScrollBars)) 
  1237.         begin
  1238.             vert := gOrigScrollBars[1];
  1239.             Horz := gOrigScrollBars[2];
  1240.             if (vert)
  1241.                 ScrollWindow('V',vert[1],vert[2]);
  1242.             if (horz)
  1243.                 ScrollWindow('H',horz[1],horz[2]);
  1244.         end;
  1245.         LogStr("==== Done restoring window titled ∂"{theTitle}∂""); 
  1246.         returnVal := 1;
  1247.     end;
  1248.     else
  1249.         Logstr("!@#$% Couldn't select the window");
  1250.     return(returnVal);
  1251. end;    # ResetWindow()
  1252.  
  1253.  
  1254. ########################################################################
  1255. #                        SelectWindow(pSpecifier)
  1256. #=======================================================================
  1257. # Author:        NJV
  1258. # Description:    This routine will select a window specified by
  1259. #                <pSpecifier>.
  1260. # Parameters:    pSpecifier - holds the title or ordinality or window descriptor
  1261. #                            of window to select.
  1262. # Returns:        {theDesc} - Updated window descriptor - Selected window OK
  1263. #                 0 - Couldn't find window to select
  1264. #=======================================================================
  1265. # History:
  1266. # KTA    7/19/93    Updated theDesc so descriptor is not embedded in a list.
  1267. # ML    11/22/94    Added error handling support
  1268. # JC    2/6/96      Changed all window .r (Rect) traits to .b (bound) traits.
  1269. ########################################################################
  1270. TASK SelectWindow(pSpecifier := 0) 
  1271. begin
  1272.     returnVal := 0;            # Init error condition
  1273.     theWind := FindWindow(pSpecifier);
  1274.     if (theWind)
  1275.     begin
  1276.         windOrd := theWind.o;
  1277.         title := theWind.t;
  1278.         boundRect := theWind.b;
  1279.         if(windOrd <> 1)
  1280.         begin
  1281.             UnCoverWindow(pSpecifier);
  1282.             _select ([window o:windOrd t:title]!,1);
  1283.             Logstr("Selected window of ordinality {windOrd} (titled '{title}')");
  1284.             theDesc := [window t:title b:boundRect];        # Call FindWindow with title and bound rect
  1285.             returnVal := FindWindow(theDesc);            # return the updated window descriptor
  1286.         end;
  1287.         else        # The specified window is already o:1
  1288.             returnVal := theWind;
  1289.     end;
  1290.     else 
  1291.         Logstr("!@#$% Couldn't select the window");
  1292.     return(returnVal);
  1293. end;  # SelectWindow()
  1294.  
  1295.  
  1296. ########################################################################
  1297. #                        UnCoverWindow(pSpecifier, pFrontWindow)
  1298. #=======================================================================
  1299. # Author:        KTA
  1300. # Description:    This routine will move a window out of the way if it covers
  1301. #                our desired window.
  1302. # Parameters:    pSpecifier -    holds the title or ordinality of window that is desired.
  1303. #                pFrontWindow - window that is in front of the desired one.
  1304. # Returns:        Nothing
  1305. #=======================================================================
  1306. # History:
  1307. # KTA    7/20/93    Updated window descriptor so it is not contained with in a list.
  1308. # KTA    11/8/93    Updated so it is possible to pass in pFrontWindow which
  1309. #                is a window specifier (integer, string, or descriptor)
  1310. # ML    11/22/94 Added error handling support
  1311. # JC    2/6/96      Changed all window .r (Rect) traits to .b (bound) traits.
  1312. ########################################################################
  1313. TASK UnCoverWindow(pSpecifier, pFrontWindow := 1)
  1314. begin
  1315.     returnVal := 0;
  1316.     desiredWindow := FindWindow(pSpecifier);
  1317.     windOrd := desiredWindow.o;
  1318.     theTitle := desiredWindow.t;
  1319.     boundRect := desiredWindow.b;
  1320.     theDesc := [window t:theTitle  o:windOrd];
  1321.     if (windOrd <> 1)        # Desired window is not the frontmost window
  1322.     begin                    # target window not frontmost
  1323.     
  1324.          try match [screen r:?theScreenRect m:true]!;
  1325.          catch theError
  1326.              ExceptionDispatcher(theError);
  1327.             
  1328.         # See if there is another window in front of it 
  1329.         if not(pFrontWindow)
  1330.             pFrontWindow := [window g:true z:true];
  1331.         
  1332.         frontwindow := FindWindow(pFrontWindow);
  1333.         newOrd := frontwindow.o;
  1334.         FboundRect := frontwindow.b;
  1335.         Front := frontwindow.t;
  1336.         
  1337.         frontDesc := [window o:newOrd t:Front]; 
  1338.         if (newOrd < windOrd)
  1339.         begin
  1340.             # see if target window is covered up - if so, uncover
  1341.             coverup := CoverCompletely(frontDesc,theDesc);
  1342.             if (coverup)
  1343.             begin        # move front window aside to show target window
  1344.                 if (boundRect[1] <= 0)
  1345.                     DragWindow(20,FboundRect[2],frontDesc,1);
  1346.                 else if (boundRect[3] >= theScreenRect[3])
  1347.                     DragWindow(-20,FboundRect[2],frontDesc,1);
  1348.                 else 
  1349.                     DragWindow(boundRect[1]+20,FboundRect[2],frontDesc,1);
  1350.             end;
  1351.         end;
  1352.     end;
  1353. end;
  1354. #########################################################################
  1355. #    DragWindow(pHorizontalPixels, pVerticalPixels,pSpecifier,pAbsolutely)
  1356. #========================================================================
  1357. # Author:        KTA
  1358. # Description:    This routine will drag the specified window.
  1359. #                <pHorizontalPixels> pixels horizontally (negative drags left) 
  1360. #                and <pVerticalPixels> pixels vertically (negative drags up)
  1361. # Parameters:    pHorizontalPixels - Horizontal pixel offset to drag the window
  1362. #                pVerticalPixels    - Vertical pixel offset to drag the window
  1363. #                pSpecifier - Window specifier
  1364. #                pAbsolutely -    1 if absolute drag
  1365. #                                0 if relative drag
  1366. # Returns:        1 - Dragged window OK
  1367. #                0 - Couldn't find window to drag
  1368. #========================================================================
  1369. # History:
  1370. # KTA    8/24/93        TCS stack parity check
  1371. # KTA    9/21/93        Added a TCSStr to the TCSEnd call, which descibes the action
  1372. # KTA    3/15/94        Added outputting ordinality.
  1373. # ML    11/22/94    Added error handling support
  1374. # KTA    12/21/94    Removed errant {str1}
  1375. #########################################################################
  1376. TASK DragWindow(pHorizontalPixels := "Random", pVerticalPixels := "Random", pSpecifier := 0,pAbsolutely := 1) 
  1377. begin
  1378.     if (global gScreenInset)
  1379.         inset := gScreenInset;
  1380.     else
  1381.         inset := { 0,20,10,10};
  1382.     noErrorFlag := 0;            # Init error condition
  1383.     if (pHorizontalPixels = "Random") or (pHorizontalPixels = "RandomReturn") 
  1384.     begin                                # user wants random coordinates
  1385.         if (pHorizontalPixels = "RandomReturn")
  1386.             RandReturn := 1;
  1387.         xyRandom := getXYRandom(inset);
  1388.         pHorizontalPixels := xyRandom[1];
  1389.         pVerticalPixels := xyRandom[2];
  1390.     end;
  1391.  
  1392.     theWind := FindWindow(pSpecifier);
  1393.     if (theWind) begin
  1394.         windOrd := theWind.o;
  1395.         title := theWind.t;
  1396.  
  1397.         if (RandReturn)         # Save original coordinates
  1398.         begin
  1399.             origH := theWind.r[1];
  1400.             origV := theWind.r[2];
  1401.         end;            
  1402.         TCSStart({ 1, global kTCSetUIWindowDrag },"DragWindow");        # Start TCS
  1403.         if (pAbsolutely) 
  1404.         begin
  1405.             _drag ([window o:windOrd t:title]!, 'a',{pHorizontalPixels,pVerticalPixels},1);                        #To drag the window
  1406.             str := "Dragged window titled '{title}' (ordinality '{windOrd}') to absolute location ∂({pHorizontalPixels},{pVerticalPixels}∂)";
  1407.             noErrorFlag := 1;
  1408.         end;
  1409.         else 
  1410.         begin
  1411.             _drag ([window o:windOrd t:title]!, 'r', {pHorizontalPixels,pVerticalPixels},1);                        #To drag the window
  1412.             str := "Dragged window titled '{title}' (ordinality '{windOrd}') {pHorizontalPixels} pixels horizontally and {pVerticalPixels} pixels vertically";
  1413.             noErrorFlag := 1;
  1414.         end;
  1415.         TCSEnd({ 1, global kTCSetUIWindowDrag }, noErrorFlag,,,str);
  1416.         LogStr(str);
  1417.         if (RandReturn)             #Move back to original location
  1418.         begin
  1419.             TCSStart({ 3, global kTCSetUIWindowDrag },"DragReturn");        # Start TCS
  1420.             _drag ([window o:windOrd t:title]!, 'a', {origH,origV},1);                #To drag the window
  1421.             str := "Dragged window titled '{title}' (ordinality '{windOrd}') back to it's original location at ∂({Origh}, {Origv}∂)";
  1422.             TCSEnd({ 3, global kTCSetUIWindowDrag }, noErrorFlag,,,str);
  1423.             LogStr(str);
  1424.         end;
  1425.     end;     
  1426.     return(noErrorFlag);
  1427. end;  # DragWindow()
  1428.  
  1429.  
  1430. #########################################################################
  1431. #                    SizeWindow(pPixelsWide,pPixelsHigh,pSpecifier,pAbsolutely)
  1432. #========================================================================
  1433. # Author:        KTA
  1434. # Description:    This routine will match and resize the specified window.
  1435. #                If only the <pPixelsWide> and <pPixelsHigh> parameters are 
  1436. #                passed, the default behavior will size the first window 
  1437. #                containing a grow and zoom box pAbsolutely.  If no parameters
  1438. #                are passed, then the default behavior will generate random
  1439. #                coordinates on the main screen and resize the window
  1440. #                to an absolute size.  If the user passes in the string
  1441. #                "random" for <pPixelsWide> and <pPixelsHigh> and passes 0 for
  1442. #                the pAbsolutely parameter (for a resize relative to current size),
  1443. #                then checks are performed to assure that new size will
  1444. #                not go off of the screen.  If it does, the values will
  1445. #                be adjusted so that the largest the window can be sized
  1446. #                is to the border of the screen.
  1447. # Parameters:    pPixelsWide - the width to resize the window
  1448. #                pPixelsHigh - the height to resize the window
  1449. #                pSpecifier -    title or ordinality of window to be sized
  1450. #                pAbsolutely -    1 if resize window absolute
  1451. #                                0 if resize window relative
  1452. # Returns:        1 - Resized window OK
  1453. #                0 - Couldn't resize window
  1454. # Examples:        SizeWindow(200,400);
  1455. #========================================================================
  1456. # History:
  1457. # KTA    8/24/93        TCS stack parity check
  1458. # KTA    12/16/93    Insure that pixels wide is not smaller than 20.
  1459. # KTA    3/15/94        Added outputting of ordinality
  1460. # ML    11/22/94    Added error handling support
  1461. # JC    2/6/96      Changed all window .r (Rect) traits to .b (bound) traits.
  1462. #########################################################################
  1463. TASK SizeWindow(pPixelsWide:="random", pPixelsHigh:="random", pSpecifier := 0, pAbsolutely := 1) 
  1464. begin
  1465.     if (global gScreenInset)
  1466.         inset := gScreenInset;
  1467.     else
  1468.         inset := { 20,20,0,0};
  1469.     noErrorFlag := 0;
  1470.     TCSReturn := 0;
  1471.     theWind := FindWindow(pSpecifier);
  1472.     pSpecifier := theWind.o;
  1473.     title := theWind.t;
  1474.     sizeBox := theWind.g;
  1475.     theWindBoundRect := theWind.b;
  1476.  
  1477.     if (theWind) 
  1478.     begin    
  1479.         TCSStart({ 1, global kTCSetUIWindowSize },"SizeWindow");        # Start TCS
  1480.         if (sizeBox)
  1481.         begin
  1482.             randomFlag := 0;
  1483.             if (pPixelsWide = "random")     # user wants to size window randomly
  1484.             begin
  1485.                 if (inset[1] < 20 )                    # Insure that we do not try to size the window to smaller than 20 pixels or 
  1486.                     inset := replace(20,1,inset);    # VU will generate an "Out of bounds error"
  1487.  
  1488.                 xyRandom := getXYRandom(inset);
  1489.                 pPixelsWide := xyRandom[1];
  1490.                 pPixelsHigh := xyRandom[2];
  1491.                 randomFlag := 1;
  1492.                 if (not pAbsolutely)         # relative - include possible negative values
  1493.                 begin
  1494.                     negative := random(0,1);
  1495.                     if (negative = 1) 
  1496.                     begin
  1497.                         pPixelsWide := 0 - pPixelsWide;
  1498.                         pPixelsHigh:= 0 - pPixelsHigh;
  1499.                     end;
  1500.                 end;
  1501.             end;
  1502.             
  1503.             # pSpecifier = ordinality of window to size
  1504.             # title = title of window to size
  1505.             if (randomFlag) # make sure if random numbers were generated that new window size is on screen
  1506.             begin
  1507.                 try match [screen r:?theScrnRect]!;
  1508.                 catch theError
  1509.                     ExceptionDispatcher(theError);
  1510.                 if (pAbsolutely)    # get Top-Left corner coord of window
  1511.                 begin
  1512.                     if ((theWindBoundRect[1] + pPixelsWide) > theScrnRect[3])        # pPixelsWide value off of screen - adjust it
  1513.                         pPixelsWide := theScrnRect[3] - theWindBoundRect[1];
  1514.                     if ((theWindBoundRect[2] + pPixelsHigh) > theScrnRect[4])        # pPixelsHigh value off of screen - adjust it
  1515.                         pPixelsHigh := theScrnRect[4] - theWindBoundRect[2];
  1516.                 end;
  1517.                 else                 # size window relative - get Bottom-Right coord of window
  1518.                 begin
  1519.                     if (not negative) 
  1520.                     begin
  1521.                         if ((theWindBoundRect[3] + pPixelsWide) > theScrnRect[3])        # pPixelsWide value off of screen
  1522.                             pPixelsWide := theScrnRect[3] - theWindBoundRect[3];
  1523.                         if ((theWindBoundRect[4] + pPixelsHigh) > theScrnRect[4])        # pPixelsHigh value off of screen
  1524.                             pPixelsHigh := theScrnRect[4] - theWindBoundRect[4];
  1525.                     end;
  1526.                     ### the 20 in the equations below must be there.  This is to assure that
  1527.                     ### the window is not sized below 20 horizontally (the size box is 20 pixels,
  1528.                     ### and attempts to size smaller than that will cause VU to display an
  1529.                     ### "Out of bounds" error.
  1530.                     else begin        # negative value - must check against upper-left corner of screen
  1531.                         if ((theWindBoundRect[3] + pPixelsWide - 20) < theScrnRect[1])        # pPixelsWide value off of screen
  1532.                             pPixelsWide := 20 - theWindBoundRect[3] - theScrnRect[1];
  1533.                         if ((theWindBoundRect[4] + pPixelsHigh - 20) < theScrnRect[2])        # pPixelsHigh value off of screen
  1534.                             pPixelsHigh := 20 - theWindBoundRect[4] - theScrnRect[2];
  1535.                     end;
  1536.                 end;
  1537.             end;
  1538.             if (pAbsolutely) 
  1539.             begin
  1540.                 try size [window t:title o:pSpecifier g:true] W:pPixelsWide H:pPixelsHigh;                        #To size the window
  1541.                 catch sizeError
  1542.                     ExceptionDispatcher(sizeError);
  1543.  
  1544.                 if not (sizeError)
  1545.                 begin
  1546.                     try match [window t:title o:pSpecifier g:true b:?theWindBoundRect]!;
  1547.                     catch theError
  1548.                         ExceptionDispatcher(theError);
  1549.  
  1550.                     pPixelsWide := theWindBoundRect[3] - theWindBoundRect[1];
  1551.                     pPixelsHigh := theWindBoundRect[4] - theWindBoundRect[2];
  1552.                     str := "Resized window '{title}' (ordinality '{pSpecifier}') absolute {pPixelsWide} pixels wide and {pPixelsHigh} pixels high";
  1553.                     noErrorFlag := 1;
  1554.                 end;
  1555.             end;
  1556.             else 
  1557.             begin
  1558.                 if (randomFlag)                # include negative offsets for random size
  1559.                 begin
  1560.                     try match [window t:title o:pSpecifier g:true b:?theOrigWindRect]!;
  1561.                     catch theError
  1562.                         ExceptionDispatcher(theError);
  1563.  
  1564.                     try size [window t:title o:pSpecifier g:true ] r:{ pPixelsWide, pPixelsHigh };  #To size the window
  1565.                     catch sizeError
  1566.                         ExceptionDispatcher(sizeError);
  1567.  
  1568.                     if not (sizeError)
  1569.                     begin
  1570.                         try match [window t:title o:pSpecifier g:true b:?theWindBoundRect]!;
  1571.                         catch theError
  1572.                             ExceptionDispatcher(theError);
  1573.  
  1574.                         pPixelsWide := theWindBoundRect[3] - theOrigWindRect[3];
  1575.                         pPixelsHigh := theWindBoundRect[4] - theOrigWindRect[4];
  1576.                         str := "Resized window '{title}' (ordinality '{pSpecifier}') relative {pPixelsWide} pixels wide and {pPixelsHigh} pixels high";
  1577.                         noErrorFlag := 1;
  1578.                     end;
  1579.                 end;
  1580.                 else 
  1581.                 begin
  1582.                     try size [window t:title o:pSpecifier g:true] r:{ pPixelsWide, pPixelsHigh };     #To size the window
  1583.                     catch sizeError
  1584.                         ExceptionDispatcher(sizeError);
  1585.  
  1586.                     if not (sizeError)
  1587.                     begin
  1588.                         try match [window t:title o:pSpecifier g:true b:?theWindBoundRect]!;
  1589.                         catch theError
  1590.                             ExceptionDispatcher(theError);
  1591.  
  1592.                         pPixelsWide := theWindBoundRect[3] - pPixelsWide;
  1593.                         pPixelsHigh := theWindBoundRect[4] - pPixelsHigh;
  1594.                         str := "Resized window '{title}' (ordinality '{pSpecifier}') relative {pPixelsWide} pixels wide and {pPixelsHigh} pixels high";
  1595.                         noErrorFlag := 1;
  1596.                     end;
  1597.                 end;
  1598.             end;
  1599.         end;    # Is sizeBox
  1600.         else     # No sizeBox
  1601.             sizeError := 1;
  1602.         ##### Error handling for Size window #####
  1603.         if (sizeError)        # if there was no error, failStr = ""
  1604.         begin
  1605.             if(sizeError = -1106)
  1606.             begin
  1607.                 str := "Couldn't size window (ordinality '{pSpecifier}'), SizeBox was off screen (ScriptError = -1106)";
  1608.                 TCSReturn := -1;
  1609.             end;
  1610.             else if(sizeError = -1130)
  1611.                 str := "Couldn't size window (ordinality '{pSpecifier}'), window not active (ScriptError = -1130)";
  1612.             else if(sizeError = 1)
  1613.                 str := "No size box found in window titled '{title}' (ordinality '{pSpecifier}'),";
  1614.             else
  1615.                 str := "Couldn't size window (ordinality '{pSpecifier}'), an error occurred while attempting to size to coords ({pPixelsWide},{pPixelsHigh}) - (ScriptError = {sizeError})";
  1616.     
  1617.             TCSInfoStr := "";
  1618.             FailStr := Str;
  1619.         end;
  1620.         else    # No sizeError (sized correctly)
  1621.         begin
  1622.             TCSReturn := noErrorFlag;
  1623.             FailStr := "";
  1624.             TCSInfoStr := "Sized window titled '{title}' (ordinality '{pSpecifier}') to coords ({pPixelsWide},{pPixelsHigh})";
  1625.         end;
  1626.         
  1627.         TCSEnd({ 1, global kTCSetUIWindowSize }, TCSReturn, FailStr,,TCSInfoStr);
  1628.         LogStr(str);
  1629.     end;
  1630.     return(noErrorFlag);    
  1631. end;  # SizeWindow()
  1632.  
  1633.  
  1634. #########################################################################
  1635. #                            ZoomWindow(pSpecifier)
  1636. #========================================================================
  1637. # Author:        KTA
  1638. # Description:    Selects the zoom box on the specified window.  If no
  1639. #                parameters are passed, then the default behavior will
  1640. #                zoom the first window with a zoom box.
  1641. # Parameters:    pSpecifier - window specifier
  1642. # Returns:        0 - Couldn't zoom the window
  1643. #                1 - Zoomed the window OK
  1644. #========================================================================
  1645. # History:
  1646. # KTA    8/24/93        TCS stack parity check
  1647. # KTA    3/15/94        Added outputting of ordinality
  1648. # ML    11/22/94    Added error handling support
  1649. # JC     2/7/96     Removed "theRect := theWind.r;                        # njv - added 6/25/91
  1650. #                            theHitPoint := {theRect[3]-20,theRect[2]};    # hit point for zoom box
  1651. #                            hitPointOffScreen := true;" they were not being used.
  1652. #                            
  1653. #########################################################################
  1654. TASK ZoomWindow(pSpecifier:= 0) 
  1655. begin
  1656.     noErrorFlag := 0;            # Init error condition
  1657.     TCSReturn := 0;                # Init TCS Return value
  1658.     FailStr := "";                # Init fail string
  1659.     TCSInfoStr := "";
  1660.     theWind := FindWindow(pSpecifier);
  1661.     if theWind begin
  1662.         windOrd := theWind.o;
  1663.         title := theWind.t;
  1664.         zoomBox := theWind.z;
  1665.                     
  1666.         TCSStart({ 1, global kTCSetUIWindowMiscOp }, "Zoom");                # TCS Start
  1667.         if (zoomBox) 
  1668.         begin
  1669.             try zoom [window o:windOrd t:title]!;    #To zoom the window
  1670.             catch zoomError
  1671.                 ExceptionDispatcher(zoomError);
  1672.             
  1673.             if (not zoomError)
  1674.             begin
  1675.                 str := "Zoomed window titled '{title}' (ordinality '{windOrd}')";
  1676.                 noErrorFlag := 1;            # Success!
  1677.             end;
  1678.         end;
  1679.         else        # No ZoomBox
  1680.             zoomError := 1; 
  1681.  
  1682.         ##### Error handling for Zoom window #####
  1683.         if (zoomError)        # if there was no error, failStr = ""
  1684.         begin
  1685.             if(zoomError = -1106)
  1686.             begin
  1687.                 str := "Couldn't zoom window titled '{title}' (ordinality '{windOrd}'), ZoomBox was off screen (ScriptError = -1106)";
  1688.                 TCSReturn := -1;
  1689.             end;
  1690.             else if(zoomError = -1130)
  1691.                 str := "Couldn't zoom window titled '{title}' (ordinality '{windOrd}'), window not active (ScriptError = -1130)";
  1692.             else if(zoomError = 1)
  1693.                 str := "No zoom box found in window titled '{title}' (ordinality '{windOrd}')";
  1694.             else
  1695.                 str := "Couldn't zoom window titled '{title}' (ordinality '{windOrd}'), an error occurred (ScriptError = {sizeError})";
  1696.     
  1697.             FailStr := Str;
  1698.         end;
  1699.         else    # No zoomError (zoomed correctly)
  1700.         begin
  1701.             TCSReturn := noErrorFlag;    # Normally this will be a 1 indicating success
  1702.             FailStr := "";                # No FailStr since success
  1703.             TCSInfoStr := Str;
  1704.         end;
  1705.         
  1706.         TCSEnd({ 1, global kTCSetUIWindowMiscOp }, TCSReturn, FailStr,,TCSInfoStr);
  1707.         LogStr(str);
  1708.     end; 
  1709.     return(noErrorFlag);
  1710. end;  # ZoomWindow()
  1711.  
  1712. #########################################################################
  1713. #                CloseWindow(pHowClose, pOverwrite, pSpecifier,pNewDocName)
  1714. #========================================================================
  1715. # Author:        KTA/NJV/DMM
  1716. # Description:    This routine will close the specified window.  If no
  1717. #                parameters are passed to this routine, the default behavior
  1718. #                will select the close box of the first window with a close box.
  1719. # Parameters:    pHowClose -    0 -    tries all three ways noted below to close the
  1720. #                                window (if needed)
  1721. #                            1 -    tries to close window by selecting "Close" menu
  1722. #                                item
  1723. #                            2 -    tries to close window by typing "Close" menu
  1724. #                                item's key equivalent
  1725. #                            3 -    tries to close window by selecting window's
  1726. #                                close box
  1727. #                pOverwrite -    0 -    will select "No" from a save-changes dialog
  1728. #                                if one appears when closing window
  1729. #                            1 -    will select "Yes" to save changes
  1730. #                pSpecifier - window specifier
  1731. #                pNewDocName - string holding new document name - if pOverwrite
  1732. #                            parameter is 1, then pNewDocName will be used for
  1733. #                            naming the file.
  1734. # Returns:        1 - Closed window OK
  1735. #                0 - Couldn't find window to close
  1736. #========================================================================
  1737. # History:
  1738. # KTA    7/19/93        Removed theWind descriptor from being embedded in a list
  1739. # KTA    7/23/93        Added a wait(2) prior to 'Save Document?? check also made
  1740. #                    call to IsStandardFile instead of matching 'DeskTop' button.
  1741. # KTA    8/24/93        TCS stack parity check
  1742. # KTA    12/01/93    Enhanced check if window was closed to also check by the 
  1743. #                     rect of the window. (bug 1120098)
  1744. # ML    11/22/94    Added error handling support
  1745. # JC    2/6/96      Changed all window .r (Rect) traits to .b (bound) traits.
  1746. ###########################################################################
  1747. TASK CloseWindow(pHowClose := 3,pOverWrite := 1,pSpecifier := 0,pNewDocName :="") 
  1748. begin
  1749.     noErrorFlag := 0;
  1750.  
  1751.     theWind := FindWindow(pSpecifier);    # Find the specified window
  1752.     if (theWind) begin                    # IF - we found the window
  1753.         ord := theWind.o;                # make assignments
  1754.         theTitle := theWind.t;
  1755.         theGrow := theWind.g;
  1756.         theZoom := theWind.z;
  1757.         theBoundRect := theWind.b;
  1758.         if (ord <> 1)
  1759.         begin
  1760.             SelectWindow(ord);        # Select the window if it's not the frontmost
  1761.             theWind := FindWindow([window t:theTitle g:theGrow z:theZoom]!);
  1762.             ord := theWind.o;        # Reassign Ord because selection may have changed ordinality
  1763.         end;
  1764.         if (not pHowClose)            # Try all methods until one works
  1765.             pHowClose := {1,2,3};
  1766.         else
  1767.             pHowClose := {pHowClose};    # Just use the specified method
  1768.             
  1769.         numItems := Card(pHowClose);
  1770.         for i := 1 to numItems        # Execute once if way to close is specified 
  1771.         begin                        # otherwise three times attempting all methods
  1772.             closeMethod := pHowClose[i];
  1773.             if (closeMethod = 1) begin        # Close with menu item
  1774.                 TCSNum := 2;
  1775.                 TCSStart({ TCSNum, global kTCSetUIWindowClose }, "CloseFromFileMenu");
  1776.                 if(SelectMenuItem("Close","File"))
  1777.                     noErrorFlag := 1;        # Success
  1778.             end;
  1779.             else if (closeMethod = 2) begin        # Close with key equivelant
  1780.                 closeKey := _match ([menuItem t:"Close"]);
  1781.                 TCSNum := 2;
  1782.                 TCSStart({ TCSNum, global kTCSetUIWindowClose }, "CloseFromKeyEq");
  1783.                 if (closeKey.k) begin
  1784.                     KeyEq(closeKey.k);
  1785.                     noErrorFlag := 1;        # Success
  1786.                 end;
  1787.             end;
  1788.             else if (closeMethod = 3) begin        # Close with close box
  1789.                 TCSNum := 1;
  1790.                 TCSStart({ TCSNum, global kTCSetUIWindowClose }, "CloseBox");
  1791.                 if (theWind.c)
  1792.                 begin
  1793.                     _close ([window o:ord t:theTitle c:true]!,1);
  1794.                     LogStr("Selected the close box on window titled '{theTitle}' (ordinality '{ord}')");
  1795.                     noErrorFlag := 1;        # Success
  1796.                 end;
  1797.                 else
  1798.                     LogStr("Couldn't find the close box on window titled '{theTitle}' (ordinality '{ord}')");
  1799.             end;
  1800.     
  1801.             if (noErrorFlag)             # IF - we had a success        
  1802.                 i := numItems;            # break because window should be closed
  1803.         end;
  1804.  
  1805.         if (noErrorFlag)                  # IF - we had a success    
  1806.         begin
  1807.             wait(2);                    # Wait to allow dialog to appear
  1808.             if(checkYesNo(pOverWrite))    # Check if a 'Save Document??' dialog appeared
  1809.             begin
  1810.                 if(pOverWrite)            # if the dialog appeared and we want to save 
  1811.                 begin
  1812.                     if (IsStandardFile())        # check for Standard File
  1813.                     begin
  1814.                         SaveAs(pNewDocName,true);
  1815.                         theTitle := Global gLastSavedFile;
  1816.                     end;
  1817.                 end;
  1818.             end;
  1819.         end;
  1820.  
  1821.         if(_matchBoolean ([window t:theTitle b:theBoundRect]!))      # Is the window we just closed still open
  1822.         begin
  1823.             LogStr("!@#$% Sorry, the window - {theTitle} is still open");
  1824.             noErrorFlag := 0;
  1825.         end;
  1826.         TCSEnd({ TCSNum, global kTCSetUIWindowClose }, noErrorFlag);                # End TCS
  1827.     end;
  1828.     return(noErrorFlag);                # Return Result
  1829. end; # CloseWindow()
  1830.  
  1831. ########################################################################
  1832. #                            ScrollWindow(pWhichScrollBar,pDesirePosition,pMaxPosition)
  1833. #=======================================================================
  1834. # Author:        KTA/NJV
  1835. # Description:    This routine will scroll the specified scrollbar on
  1836. #                the active window.
  1837. # Parameters:    pWhichScrollBar = 'H' - for horizontal scrollbar
  1838. #                                = 'V' - for vertical scrollbar
  1839. #                <pDesirePosition><pMaxPosition> = the fraction pDesirePosition/pMaxPosition
  1840. # Returns:        0 - Couldn't scroll the scroll bar
  1841. #                1 - Scrolled the scroll bar
  1842. # Examples:        ScrollWindow('H',1,2)  will scroll the horizontal bar 1/2
  1843. # Assumptions:    That the scrollbars are present. This routine collects
  1844. #                only the first two scroll bars, which are assumed to be 
  1845. #                the horizontal and vertical scroll bars. 
  1846. #                This routine is not 100% reliable.
  1847. #=======================================================================
  1848. # History:
  1849. # KTA    8/24/93        TCS stack parity check
  1850. # KTA    9/10/93        Better check to see if scroll bars are on screen
  1851. # ML    11/22/94    Added error handling support
  1852. #########################################################################
  1853. TASK ScrollWindow(pWhichScrollBar,pDesirePosition:=-1,pMaxPosition:=-1) 
  1854. begin
  1855.     returnVal := 0;
  1856.     failStr := '';
  1857.     theScrollBars := GetVHScrollBars();
  1858.     theScreen := _match([screen]);
  1859.     if (theScrollBars)
  1860.     begin
  1861.         vertical := theScrollBars[1];
  1862.         verticalDiff := vertical.s;
  1863.         horizontal := theScrollBars[2];
  1864.         horizontalDiff := horizontal.s;
  1865.  
  1866.         if (pWhichScrollBar = 'V') or (pWhichScrollBar = 'v') 
  1867.         begin
  1868.             if (pDesirePosition=-1) or (pMaxPosition=-1)     # generate random value
  1869.             begin
  1870.                 pDesirePosition := random(0,verticalDiff[2]);
  1871.                 pMaxPosition := verticalDiff[2];
  1872.             end;
  1873.             TCSNum := 1;
  1874.             TCSStart({ TCSNum, global kTCSetUIWindowScroll },"VerticalScroll");        # Start TCS
  1875.             if not(vertical.s = {0,0}) #Test to see if Scrollbars are enabled
  1876.             begin
  1877.                 if (vertical.e)         #Test to see if Scrollbars are enabled
  1878.                 begin
  1879.                     if(vertical.r[1] < theScreen.r[3])
  1880.                     begin
  1881.                         try scroll vertical a:{pDesirePosition,pMaxPosition};
  1882.                         catch scrollError
  1883.                             ExceptionDispatcher(scrollError);
  1884.  
  1885.                         if not (scrollError)
  1886.                         begin
  1887.                             LogStr("Scrolled the vertical scroll bar Absolute ({pDesirePosition}, {pMaxPosition})");
  1888.                             returnVal := 1;
  1889.                         end;
  1890.                     end;
  1891.                     else
  1892.                     begin
  1893.                         LogStr("!@#$% The vertical scroll bar is off the screen");
  1894.                         failStr := "!@#$% The vertical scroll bar is off the screen";
  1895.                     end;
  1896.                 end;
  1897.                 else
  1898.                 begin
  1899.                     LogStr("!@#$% The vertical scroll bar was not enabled to scroll");
  1900.                     failStr := "!@#$% The vertical scroll bar was not enabled to scroll";
  1901.                 end;
  1902.             end;
  1903.             else
  1904.             begin
  1905.                 LogStr("!@#$% The vertical scroll bar was not enabled to scroll - no thumbnail");
  1906.                 failStr := "!@#$% The vertical scroll bar was not enabled to scroll - no thumbnail";
  1907.             end;
  1908.         end;
  1909.         else 
  1910.         begin
  1911.             if (pDesirePosition=-1) or (pMaxPosition=-1)     # generate random value
  1912.             begin
  1913.                 pDesirePosition := random(0,horizontalDiff[2]);
  1914.                 pMaxPosition := horizontalDiff[2];
  1915.             end;
  1916.             TCSNum := 2;
  1917.             TCSStart({ TCSNum, global kTCSetUIWindowScroll },"HorizontalScroll");        # Start TCS
  1918.             if not(horizontal.s = {0,0}) #Test to see if Scrollbars are enabled
  1919.             begin
  1920.                 if (horizontal.e)         #Test to see if Scrollbars are enabled
  1921.                 begin
  1922.                     if(horizontal.r[2] < theScreen.r[4])
  1923.                     begin
  1924.                         try scroll horizontal a:{pDesirePosition,pMaxPosition};
  1925.                         catch scrollError
  1926.                             ExceptionDispatcher(scrollError);
  1927.  
  1928.                         if not (scrollError)
  1929.                         begin
  1930.                             LogStr("Scrolled the horizontal scroll bar absolute ({pDesirePosition}, {pMaxPosition})");
  1931.                             returnVal := 1;
  1932.                         end;
  1933.                     end;
  1934.                     else
  1935.                     begin
  1936.                         LogStr("!@#$% The horizontal scroll bar is off the screen");
  1937.                         failStr := "!@#$% The horizontal scroll bar is off the screen";
  1938.                     end;
  1939.                 end;
  1940.                 else
  1941.                 begin
  1942.                     LogStr("!@#$% The horizontal scroll bar was not enabled to scroll");
  1943.                     failStr := "!@#$% The horizontal scroll bar was not enabled to scroll";
  1944.                 end;
  1945.             end;
  1946.             else
  1947.             begin
  1948.                 LogStr("!@#$% The horizontal scroll bar was not enabled to scroll - no thumbnail");
  1949.                 failStr := "!@#$% The horizontal scroll bar was not enabled to scroll - no thumbnail";
  1950.             end;
  1951.         end;
  1952.         if(scrollError)
  1953.         begin
  1954.             if (scrollError = -1150)
  1955.                 failStr := failstr + "Couldn't scroll because the scroll bar is off the screen";
  1956.         end;
  1957.         if not(returnVal)
  1958.             TCSReturn := -1;     # Feature not available
  1959.         else
  1960.             TCSReturn := 1;
  1961.     
  1962.         TCSEnd({ TCSNum, global kTCSetUIWindowScroll }, TCSReturn,failStr);
  1963.     end;
  1964.     return(returnVal);
  1965. end;  # ScrollWindow()
  1966.  
  1967. ########################################################################
  1968. #                            GetVHScrollBars()
  1969. #=======================================================================
  1970. # Author:            NJV
  1971. # Description:        This routine will return the vertical and horizontal
  1972. #                    scroll bars.
  1973. # Parameters:        pSpecifier - Window descriptor 
  1974. # Returns:            0 - Couldn't find scroll bars
  1975. #                    {vertical,horizontal} - list of vertical and horizontal
  1976. #                                            scroll bars
  1977. # Examples:            scrollBars := GetVHScrollBars();
  1978. # Assumptions:        Top of vertical scroll bar is at a lower vertical value
  1979. #                    that the horizontal (i.e. the top of vertical rect is smaller
  1980. #                    than the top of the horizontal scroll bar's rect).
  1981. #=======================================================================
  1982. # History:
  1983. # ML    11/22/94 Added error handling support
  1984. # KTA    1/31/95     Added parameter pSpecifier
  1985. #########################################################################
  1986. TASK GetVHScrollBars(pSpecifier := [window c:true g:true]) begin
  1987.     ScrollWindowlist := _collect([scrollbar w:pSpecifier]!);
  1988.     if not (card(ScrollWindowlist)) begin
  1989.         LogStr("!@#$% There were no recognizable scroll bars present");
  1990.         return(0);
  1991.     end;
  1992.     Rec1 := ScrollWindowlist[1];
  1993.     Rec2 := ScrollWindowlist[2];
  1994.     Rec1R := Rec1.r[1];
  1995.     Rec2R := Rec2.r[1];
  1996.  
  1997.     if (Rec1R < Rec2R) begin         #To determine which scroll bar is Vertical/Horizontal
  1998.         horizontal := Rec1;
  1999.         vertical := Rec2;
  2000.     end;
  2001.     else begin
  2002.         horizontal := Rec2;
  2003.         vertical := Rec1;
  2004.     end;
  2005.     return({vertical,horizontal});
  2006. end;
  2007.  
  2008. #########################################################################
  2009. #                         CloseAllWindows()
  2010. #=======================================================================
  2011. # Author:          ML
  2012. # Description:    Closes all windows having a close box.
  2013. # Parameters:    None
  2014. # Returns:        Nothing
  2015. # Assuptions:    Windows have close boxes.
  2016. #=======================================================================
  2017. # History:
  2018. # KTA    2/10/95 Call findWindow with booleanFlag set
  2019. ########################################################################
  2020. TASK CloseAllWindows()
  2021. begin
  2022.     KeepGoingFlag := 1;
  2023.     While (KeepGoingFlag)
  2024.     begin
  2025.         if (FindWindow([window c:true]!, true))
  2026.             KeepGoingFlag:= CloseWindow(,,[window c:true]!);
  2027.         else
  2028.             KeepGoingFlag:=0;
  2029.     end;
  2030. end;
  2031. #########################################################################
  2032. #                            FindWindow(pSpecifier)
  2033. #========================================================================
  2034. # Author:        DM
  2035. # Description:    FindWindow will return the descriptor of the window
  2036. #                specified by the parameter pSpecifier.
  2037. # Parameters:    pSpecifier - if string, then it holds title of window
  2038. #                            if integer, then it holds ordinality of window
  2039. #                            if rect, create a fake window specfier with the
  2040. #                                rect as the wind.r
  2041. #                            if window descriptor will match window meeting 
  2042. #                            the specified traits e.g. [window t:'Mywind' o:2]
  2043. #                            Pass 0 to get the first document window
  2044. #                pBooleanFlag - IF set will return true or false indicating the presence of 
  2045. #                                window specified by <pSpecifier>. Note: No window
  2046. #                                descriptor will be returned.
  2047. # Returns:        0 - Couldn't find the window
  2048. #                descriptor - Window descriptor that meets the specified match
  2049. #                            for <pSpecifier>
  2050. # Example:        FindWindow(1);
  2051. #========================================================================
  2052. # History:
  2053. # KTA    7/19/93        Added support for pSpecifier type 'descriptor' removed embedding into list.
  2054. # ML    11/22/94    Added error handling support
  2055. # KTA    2/10/95        Added pBooleanFlag
  2056. # JC    2/6/96      Changed "theDesc := [window r:pSpecifier t:"RECTANGLE" o:0];" to "theDesc := [window b:pSpecifier t:"RECTANGLE" o:0];".
  2057. #########################################################################
  2058. TASK FindWindow(pSpecifier := "None", pBooleanFlag := false) 
  2059. begin
  2060.     WindType := TypeOf(pSpecifier);
  2061.     if (WindType = 'descriptor')
  2062.     begin
  2063.         if(pBooleanFlag)
  2064.             theDesc := _matchBoolean (pSpecifier);
  2065.         else
  2066.             theDesc := _match (pSpecifier!,1);
  2067.     end;
  2068.     else if (WindType = 'string') or (WindType = 'regularExpression')
  2069.     begin
  2070.         if(pBooleanFlag)
  2071.             theDesc := _matchBoolean ([window t:pSpecifier]);
  2072.         else
  2073.         begin
  2074.             theDesc := _match ([window t:pSpecifier]!,1);
  2075.             if (not theDesc) 
  2076.                 LogStr("!@#$% Couldn't match a window of title {pSpecifier}");
  2077.         end;
  2078.     end;
  2079.     else if(WindType = 'integer') 
  2080.     begin
  2081.         if(pSpecifier > 0) 
  2082.         begin
  2083.             if(pBooleanFlag)
  2084.                 theDesc := _matchBoolean ([window o:pSpecifier]);
  2085.             else
  2086.             begin
  2087.                 theDesc := _match ([window o:pSpecifier]!,1);
  2088.                 if (not theDesc)
  2089.                     LogStr("!@#$% Couldn't match a window of ordinality {pSpecifier} with a grow box");
  2090.             end;
  2091.         end;
  2092.         else 
  2093.         begin
  2094.             if(pSpecifier = 0) 
  2095.             begin
  2096.                 if(pBooleanFlag)
  2097.                     theDesc := _matchBoolean ([window c:true g:true]);
  2098.                 else
  2099.                 begin
  2100.                     theDesc := _match ([window c:true g:true]!,1);
  2101.                     if (not theDesc) 
  2102.                         LogStr("!@#$% Couldn't match a window with a close and grow box");
  2103.                 end;
  2104.             end;
  2105.             else 
  2106.             begin
  2107.                 if (pSpecifier < 0) 
  2108.                 begin
  2109.                     scrList := _collect ([screen]!,1);
  2110.                     theDesc := scrList[-pSpecifier];
  2111.                     if (not theDesc) 
  2112.                     begin
  2113.                         scrOrd:=-pSpecifier;
  2114.                         LogStr("!@#$% Couldn't match a screen with ordinality {scrOrd}");
  2115.                         theDesc := [];
  2116.                     end;
  2117.                 end;
  2118.             end;
  2119.         end;
  2120.     end;
  2121.     else if(WindType = 'list')
  2122.     begin
  2123.         if((TypeOf(pSpecifier[1]) = 'integer'))
  2124.         begin
  2125.             theDesc := [window b:pSpecifier t:"RECTANGLE" o:0];
  2126.             LogStr("Faked out FindWindow with a rectangle!!");
  2127.         end;
  2128.         else            # the old way was e.g.FindWindow({[window t:'Untitled']});
  2129.             println "    +++++++++ Error: Its an old FindWindow() Descriptor";
  2130.     end;
  2131.     return (theDesc);
  2132. end; # FindWindow()
  2133.  
  2134.  
  2135. ########################################################################
  2136. #        GetRandomPointsRelativeToWindow(pInset, pSpecifier, pNumPts)
  2137. #=======================================================================
  2138. # Author:             KTA
  2139. # Description:        Determines what the rectangle is for the window specified 
  2140. #                    as Specifier and returns a random X and Y coordinate which
  2141. #                    will be inside the window if moving relative to the top 
  2142. #                    left corner of the screen or window.
  2143. # Parameters:        pInset - ltrb inset from screen or window
  2144. #                    pSpecifier
  2145. #                            Integer
  2146. #                              > 0 - Ordinality window to find coords in
  2147. #                              = O coords in window with s:doc g:true and c:true
  2148. #                              < 0 coords in specified screen.  Screen numbers
  2149. #                                are negative of pSpecifier.
  2150. #                            String
  2151. #                                title of window to find coords in
  2152. #                            {List}
  2153. #                                any partial or complete window descriptor
  2154. # Returns:            myPoints - List of random X and Y.  eg. { x, y }
  2155. #========================================================================
  2156. # History:
  2157. # JC    2/6/96      Changed all window .r (Rect) traits to .b (bound) traits.
  2158. # JC    2/6/96      Changed "pInset := { 0,20,20,20}" to "pInset := { 0,20,20,20}".
  2159. ########################################################################
  2160. TASK GetRandomPointsRelativeToWindow(pInset := { 0,0,20,20}, pSpecifier := 0, pNumPts := 1)
  2161. begin
  2162.     theDesc := FindWindow(pSpecifier);
  2163.     if(theDesc) 
  2164.     begin
  2165.         windowBoundRect := theDesc.b;
  2166.         myPoints := GetXYRandom(pInset, windowBoundRect, pNumPts);
  2167.     end;
  2168.     return(myPoints);
  2169. end;
  2170.  
  2171. #=======================================================================
  2172. # Dialog related tasks:
  2173. #=======================================================================
  2174.  
  2175. #########################################################################
  2176. #                        SelectButton(pButton)
  2177. #========================================================================
  2178. # Author:        KTA
  2179. # Description:    This routine will select the button named <pButtonName>
  2180. # Parameters:    pButton - string - holding name of button to select
  2181. #                            integer - ordinality of Button
  2182. # Returns:        0 - Couldn't select button
  2183. #                pButtonName - Selected button OK
  2184. #========================================================================
  2185. # History:
  2186. # KTA    7/6/93    Performance support: Call (gBeginTimer);
  2187. # KTA    9/13/93 Added support for selecting Buttons for by ordinality
  2188. # KTA    9/21/93 Changed gBeginTimer to gPreSelectButtonHook
  2189. # KTA    9/21/93 Changed gBeginTimer to gPreSelectButtonHook
  2190. # KTA    11/12/93 Changed select[button] to move over the button then click 
  2191. #                 for performance - doesn't require additional match. This
  2192. #                is done to reduce the amount of VU overhead required in matching
  2193. #                the button.
  2194. # KTA    11/16/93 Do logging prior to actually selecting button for performance. 
  2195. # KTA    12/01/93 Added support for button descriptors. 
  2196. # KTA    3/15/94  Added outputting ordinality.
  2197. # ML    11/22/94 Added error handling support
  2198. #########################################################################
  2199. TASK SelectButton(pButton) 
  2200. begin
  2201.     returnVal := 0;
  2202.     ParameterType := typeOf(pButton);
  2203.     if (ParameterType = 'string')
  2204.         IsButton := _match ([button t:pButton]!,1);
  2205.     else if (ParameterType = 'integer')
  2206.         IsButton := _match ([button o:pButton]!,1);
  2207.     else if (ParameterType = 'descriptor')
  2208.     begin
  2209.         if(DescType(pButton) = 'button')
  2210.             IsButton := _match (pButton!,1);
  2211.         else
  2212.             logStr("!@#$% The descriptor '{pButton}' is not a valid button descriptor");
  2213.     end;
  2214.         
  2215.     if (IsButton)
  2216.     begin
  2217.         theButtonTitle := IsButton.t;
  2218.         theButtonOrd := IsButton.o;
  2219.         if (IsButton.e) 
  2220.         begin
  2221.             LogStr( "Selecting button titled '{theButtonTitle}' (ordinality '{theButtonOrd}')");
  2222.             _move ('a', {((IsButton.r[1]+IsButton.r[3])/2),((IsButton.r[2]+IsButton.r[4])/2)});
  2223.             if (global gPreSelectButtonHook)
  2224.                 Call(gPreSelectButtonHook);
  2225.             _click();
  2226.             #Select [button t:theButtonTitle]!;
  2227.             returnVal := theButtonTitle;
  2228.         end;
  2229.         else 
  2230.             LogStr("!@#$% Couldn't select button named '{theButtonTitle}' (ordinality '{theButtonOrd}') because it's not enabled");
  2231.     end;
  2232.     else
  2233.         LogStr("!@#$% There was no button specified by '{pButton}'");
  2234.  
  2235.     return(returnVal);
  2236. end; # SelectButton()
  2237.  
  2238. #######################################################################
  2239. #                    SelectRadioButton(pRadioButton)
  2240. #========================================================================
  2241. # Author:        KTA
  2242. # Description:    This routine will select RadioButton named <pRadioButtonName>
  2243. # Parameters:    pRadioButton - string - name of radio button to select
  2244. #                                integer - radio button ordinality
  2245. # Returns:        0 - Couldn't select radio button
  2246. #                pRadioButtonName - Selected button OK
  2247. #========================================================================
  2248. # History:
  2249. # KTA    9/13/93 Added support for selecting radioButtons for by ordinality
  2250. # KTA    3/15/94 Added outputting ordinality
  2251. # KTA    9/20/94 Select by title and ordinality instead of just ordinality
  2252. # ML    11/22/94 Added error handling support
  2253. #########################################################################
  2254. TASK SelectRadioButton(pRadioButton) 
  2255. begin
  2256.     returnVal := 0;
  2257.     if (typeOf(pRadioButton) = 'string')
  2258.         IsRadioButton := _match ([RadioButton t:pRadioButton]!,1);
  2259.     else if (typeOf(pRadioButton) = 'integer')
  2260.         IsRadioButton := _match ([RadioButton o:pRadioButton]!,1);
  2261.         
  2262.     if (IsRadioButton) 
  2263.     begin
  2264.         theRadioButtonTitle := IsRadioButton.t;
  2265.         theRadioButtonOrd := IsRadioButton.o;
  2266.         if (IsRadioButton.e) 
  2267.         begin
  2268.             _Select ([RadioButton t:theRadioButtonTitle o:theRadioButtonOrd]);
  2269.             str := "Selected radio button titled '{theRadioButtonTitle}' (ordinality '{theRadioButtonOrd}')";
  2270.             returnVal := theRadioButtonTitle;
  2271.         end;
  2272.         else
  2273.             str := "!@#$% Couldn't select radio button named '{theRadioButtonTitle}' (ordinality '{theRadioButtonOrd}') because it's not enabled";
  2274.     end;
  2275.     else
  2276.         str := "!@#$% There was no radio button specified by '{pRadioButton}'";
  2277.  
  2278.     LogStr(str);
  2279.     return(returnVal);
  2280. end; # SelectRadioButton()
  2281.  
  2282. #########################################################################
  2283. #                        SelectCheckBox(pCheckBox)
  2284. #========================================================================
  2285. # Author:        KTA
  2286. # Description:    This routine will select CheckBox named <pCheckBoxName>
  2287. # Paramters:    pCheckBox - string - name of check box to select
  2288. #                            integer - ordinality of checkBox
  2289. # Returns:        0 - Couldn't select check box
  2290. #                pCheckBoxName - Selected check box OK
  2291. #========================================================================
  2292. # History:
  2293. # KTA    9/13/93 Added support for selecting CheckBox for by ordinality
  2294. # KTA    3/15/94 Added outputting ordinality
  2295. # KTA    9/20/94 
  2296. # ML    11/22/94 Added error handling support
  2297. #########################################################################
  2298. TASK SelectCheckBox(pCheckBox) 
  2299. begin
  2300.     returnVal := 0;
  2301.     if (typeOf(pCheckBox) = 'string')
  2302.         isSelectCheckBox := _match ([CheckBox t:pCheckBox]!,1);
  2303.     else if(typeOf(pCheckBox) = 'integer')
  2304.         isSelectCheckBox := _match ([CheckBox o:pCheckBox]!,1);
  2305.  
  2306.     if (isSelectCheckBox)
  2307.     begin
  2308.         theCheckBoxTitle := isSelectCheckBox.t;
  2309.         theCheckBoxOrd := isSelectCheckBox.o;
  2310.         if (isSelectCheckBox.e)
  2311.         begin
  2312.             _Select ([CheckBox t:theCheckBoxTitle o:theCheckBoxOrd ]);
  2313.             str := "Selected check box titled '{theCheckBoxTitle}' (ordinality '{theCheckBoxOrd}')";
  2314.             returnVal := theCheckBoxTitle;
  2315.         end;
  2316.         else 
  2317.             str := "!@#$% Couldn't select check box named '{theCheckBoxTitle}' (ordinality '{theCheckBoxOrd}') because it's not enabled";
  2318.     end;
  2319.     else
  2320.         str := "!@#$% There was no check box specified by '{pCheckBox}'";
  2321.  
  2322.     LogStr(str);
  2323.     return(returnVal);
  2324. end; # SelectCheckBox()
  2325.  
  2326.  
  2327. #########################################################################
  2328. #                CheckYesNo(pFlag)
  2329. #========================================================================
  2330. # Author:        SL
  2331. # Description:    Checks for dialog boxes with "Yes" (or "OK") and "No"
  2332. #                buttons. If they are found, clicks one of the buttons
  2333. #                depending on the 'pFlag' parameter.
  2334. # Parameters:    pFlag -    TRUE - Selects "Yes"  or "OK" button.
  2335. #                        FALSE - Selects "No" button.
  2336. #                DocName - Name that docment will be saved with.
  2337. # Returns:        What is returned by SelectButton
  2338. #========================================================================
  2339. # History:
  2340. #    ML    6/9/94    Handle both kinds of apostrophes in "Don't Save"
  2341. #    ML    11/22/94 Added error handling support
  2342. #    ML    2/6/95    use _MatchBoolean instead of _match
  2343. #    ML    11/21/95    add support for internationl
  2344. #    MDF 04/25/96 Fixed bug where selection of 'No' button failed when gNoString
  2345. #                 was undefined.
  2346. #########################################################################
  2347. TASK CheckYesNo(pFlag := true)
  2348. begin
  2349.     global gYesString, gOKString, gSaveString, gNoString, gDontSaveString; 
  2350.  
  2351.     if (IsUndefined (gOKString))
  2352.         okString := "OK";
  2353.     else
  2354.         okString := gOKString;
  2355.     if (IsUndefined (gYesString))
  2356.         yesString := "Yes";
  2357.     else
  2358.         yesString := gYesString;
  2359.     if (IsUndefined (gSaveString))
  2360.         saveString := "Save";
  2361.     else
  2362.         saveString := gSaveString;
  2363.     if (IsUndefined (gNoString))
  2364.         noString := "No";
  2365.     else
  2366.         noString := gNoString;
  2367.         
  2368.     if ( pFlag )  begin
  2369.         yesBtn := _matchBoolean ([button t:yesString w:[window o:1]]!);
  2370.         okBtn  := _matchBoolean ([button t:okString  w:[window o:1]]!);
  2371.         saveBtn := _matchBoolean ([button t:saveString  w:[window o:1]]!);
  2372.     
  2373.         if (yesBtn)
  2374.             return(SelectButton(yesString));
  2375.         else if (okbtn)
  2376.             return(SelectButton(okString));
  2377.         else if (saveBtn)
  2378.             return(SelectButton(saveString));
  2379.     end;
  2380.     else
  2381.     begin
  2382.         noBtn  := _matchBoolean ([button t:noString w:[window o:1]]!);
  2383.         if (noBtn)
  2384.             return(SelectButton(noString));
  2385.         else
  2386.         begin
  2387.             if (gDontSaveString)
  2388.                 IsDontSaveBtn  := _matchBoolean ([button t:gDontSaveString w:[window o:1]]!);
  2389.             else
  2390.                 IsDontSaveBtn  := _matchBoolean ([button t:/Don?t Save/  w:[window o:1]]!);
  2391.             if (IsDontSaveBtn)
  2392.             begin
  2393.                 if (gDontSaveString)
  2394.                     IsDontSaveBtn  := _match ([button t:gDontSaveString  w:[window o:1]]!,1);
  2395.                 else
  2396.                     IsDontSaveBtn  := _match ([button t:/Don?t Save/  w:[window o:1]]!,1);
  2397.                 DontSaveBtn := IsDontSaveBtn.t;
  2398.                 return(SelectButton(DontSaveBtn));
  2399.             end;
  2400.         end;
  2401.     end;
  2402. end; # CheckYesNo()
  2403.  
  2404. ########################################################################
  2405. #        DialogCheck(pFindStaticText,pCommitButton, pLogIT, pWindowDesc)
  2406. #=======================================================================
  2407. # Author:        KTA
  2408. # Description:    This routine will to match a dialog of specified by <pWindowDesc>,
  2409. #                with static text - <pFindStaticText>, if found it will select the 
  2410. #                Button - {pCommitButton}. If <pFindStaticText> is not defined a
  2411. #                match will be made on any dialog with static text.
  2412. # Parameters:    pFindStaticText - Static text string that you want to match
  2413. #                pCommitButton   - Button to select if the static text is found.
  2414. #                pLogIT - If you don't want to log the dialog pass 0
  2415. #                pWindowDesc - window descriptor of dialog
  2416. # Returns:        <Static Text> - the Static Text String found pFindStaticText 
  2417. #                and selected pCommitButton
  2418. #                0 - Couldn't find pFindStaticText
  2419. #=======================================================================
  2420. # History:
  2421. # KTA    7/6/93    Changed default pWindowDesc so it doesn't include c:False
  2422. # KTA    11/11/93    Updated so if pFindStaticText = '' it will not need to be a substring
  2423. # KTA    11/15/93    Moved ! in collect statement so it would actually work
  2424. # KTA    12/01/93    Added support for button descriptors
  2425. # ML    11/22/94     Added error handling support
  2426. # ML    12/13/94    Cleaner error handling when checking for the window
  2427. #                    remove extraneous returnval assignment
  2428. ########################################################################
  2429. TASK DialogCheck(pFindStaticText :='', pCommitButton :="", pLogIT := 1, pWindowDesc := [window o:1 c:false]) 
  2430. begin
  2431.     returnVal := 0;
  2432.     if _matchBoolean([staticText w:pWindowDesc]!)
  2433.     begin
  2434.         DialogWin :=  _collect([staticText w:pWindowDesc]!,1); 
  2435.         if (DialogWin) 
  2436.         begin
  2437.             NumStaticItems:= card (DialogWin);
  2438.             for i:= 1 to NumStaticItems 
  2439.             begin
  2440.                 StaticItem:= DialogWin[i];
  2441.                 theStaticText :=  StaticItem.t;
  2442.                 if not( theStaticText = '') 
  2443.                 begin
  2444.                     if((IsSubString(pFindStaticText, theStaticText)) or (pFindStaticText = ''))
  2445.                     begin
  2446.                         if (pLogIT) 
  2447.                             LogStr("Found Dialog: '{theStaticText}'");
  2448.                         if (pCommitButton)
  2449.                         begin
  2450.                             ParameterType := typeOf(pCommitButton);
  2451.     
  2452.                             if ((ParameterType = 'string') or (ParameterType = 'descriptor'))
  2453.                                 SelectButton(pCommitButton);
  2454.                             else if (pCommitButton = 1)
  2455.                                 SpecialKey(returnKey, "Return Key");
  2456.                             else
  2457.                                 LogStr('!@#$% Method of dismissing Dialog was not valid');
  2458.                         end;
  2459.                         returnVal := theStaticText;
  2460.                         NumStaticItems:=i;
  2461.                     end;  
  2462.                 end; 
  2463.             end; 
  2464.         end; # if (DialogWin)
  2465.     end; # if _matchBoolean([staticText w:pWindowDesc]!)
  2466.     return(returnVal);
  2467. end;  # DialogCheck()
  2468.  
  2469. #########################################################################
  2470. #                        DialogHandler(pSpecifier)
  2471. #========================================================================
  2472. # Author:        KTA 
  2473. # Description:    Keep calling DialogDimisser() while there is a dialog present.
  2474. # Parameters:    pSpecifier - dialog descriptor.
  2475. # Returns:        0 - Unsuccessful
  2476. #                -1 - There were no dialogs to dismiss
  2477. #                returnVal >= 1 - Successful All dialog were dismissed. Indicates 
  2478. #                                the number of dialogs that were idsmissed.
  2479. # Examples:        DialogHandler();
  2480. # Assumptions:    None 
  2481. #========================================================================
  2482. # History:
  2483. # KTA    3/24/94    Created    
  2484. # KTA    5/12/94    Changed the dialog window to either a movablemodal or a dialog.    
  2485. # KTA    9/21/94    Check to see if there was any statictext before concatenating strings    
  2486. # ML    11/22/94 Added error handling support
  2487. # KTA    2/10/95 If no windows, don't iterate 10 times
  2488. #########################################################################
  2489. TASK DialogHandler(pSpecifier := [window o:1 s:movablemodal c:false]!)
  2490. begin
  2491.     ReturnVal := -1; #    Default indicating no dialogs present
  2492.     StaticTextStr := '';
  2493.     dialogCount := 0;
  2494.     for i := 1 to 10    # Only iterate 10 times
  2495.     begin 
  2496.         wait(1);
  2497.         if (findwindow(pSpecifier, true) or findwindow([window o:1 s:dialog c:false]!, true))
  2498.         begin
  2499.             dialogCount := dialogCount + 1;
  2500.             try match[staticText t:?theStaticText w:pSpecifier];
  2501.             catch theError
  2502.                 ExceptionDispatcher(theError);
  2503.             if(theStaticText)
  2504.                 StaticTextStr := StaticTextStr + " / " + theStaticText;
  2505.             returnVal := DialogDismisser(, pSpecifier);
  2506.         end;
  2507.         else
  2508.             i := 10;
  2509.     end;
  2510.     if (returnVal > 0)
  2511.         returnVal := dialogCount;
  2512.         
  2513.     if(StaticTextStr)
  2514.         StaticTextStr := "Dialogs: " + StaticTextStr;
  2515.     return({returnVal, StaticTextStr});
  2516. end; # DialogHandler()
  2517.  
  2518.  
  2519.  
  2520. #########################################################################
  2521. #                        DialogDismisser(pHowToDismiss, pSpecifier)
  2522. #========================================================================
  2523. # Author:        KTA 
  2524. # Description:    Dismiss dialogs using one of several methods (or all)
  2525. # Parameters:    pHowToDismiss
  2526. #                    1 - Command - '.'
  2527. #                    2 - Escape key
  2528. #                    3 - 'Cancel' Button
  2529. #                    4 - 'No' button
  2530. #                    5 - 'Don't Save' button
  2531. #                    6 - 'OK' button
  2532. #                    7 - 'Quit' button
  2533. #                    8 - type 'Return Key' 
  2534. #                    String - 
  2535. #                        'All' - all methods above
  2536. #                        Any other string - SelectButton(<string>).
  2537. #                pSpecifier - dialog descriptor.
  2538. # Returns:        0 - Unsuccessful
  2539. #                (non-zero) - Successful All dialog were dismissed.
  2540. # Examples:        DialogDismisser();
  2541. # Assumptions:    None 
  2542. #========================================================================
  2543. # History:
  2544. # KTA    3/24/94    Created    
  2545. # ML    11/22/94 Added error handling support
  2546. # KTA    2/10/95     Call Findwindow with pBooleanFlag set
  2547. # KTA    2/10/95     Optimized, removed edittext from specifiedDialog
  2548. # ML    3/22/95     use _MatchBoolean() to check existence of pSpecifier 
  2549. # KTA    4/24/95     Changed case 9: pHowToDismiss to theButton (thanks - Mona Chow)
  2550. #    ML    11/21/95    add support for internationl
  2551. #########################################################################
  2552. TASK DialogDismisser( pHowToDismiss := 'All', pSpecifier := [window o:1 c:false]!, pSpecifiedDialog := false)
  2553. begin
  2554.     global gQuitString, gOKString, gNoString, gDontSaveString, gCancelString; 
  2555.     returnval:=0;
  2556.     newTraits := {};
  2557.     SpecifiedDialog := 0;
  2558.     if not(pSpecifiedDialog)
  2559.     begin
  2560.         if _MatchBoolean(pSpecifier)
  2561.             SpecifiedDialog:= FindWindow( pSpecifier);
  2562.         else if _MatchBoolean([window o:1 s:dialog]!)
  2563.             SpecifiedDialog := FindWindow([window o:1 s:dialog]);    # GenericDialog
  2564.     
  2565.         ## Remove any EditTextFields
  2566.         if SpecifiedDialog
  2567.         begin
  2568.             for each item in SpecifiedDialog.k
  2569.             begin
  2570.                 typeOfDescriptor := DescType(item);
  2571.                 if not(typeOfDescriptor = 'editText')
  2572.                 begin
  2573.                     sizeofTraits := card(newTraits)+1;
  2574.                     newTraits[sizeofTraits] := item;
  2575.                 end;
  2576.             end; # for each item in SpecifiedDialog.k
  2577.             SpecifiedDialog.k := newTraits;
  2578.         end; # if SpecifiedDialog
  2579.     end;
  2580.     else
  2581.         SpecifiedDialog := pSpecifiedDialog;
  2582.     
  2583.     if (SpecifiedDialog)
  2584.     begin
  2585.         
  2586.         if (IsUndefined (gOKString))
  2587.             okString := "OK";
  2588.         else
  2589.             okString := gOKString;
  2590.         if (IsUndefined (gCancelString))
  2591.             cancelString := "Cancel";
  2592.         else
  2593.             cancelString := gCancelString;
  2594.         if (IsUndefined (gSaveString))
  2595.             saveString := "Save";
  2596.         else
  2597.             saveString := gSaveString;
  2598.         if (IsUndefined (gNoString))
  2599.             noString := "No";
  2600.         else
  2601.             noString := gNoString;
  2602.         if (IsUndefined (gQuitString))
  2603.             quitString := "Quit";
  2604.         else
  2605.             quitString := gQuitString;
  2606.             
  2607.         if(TypeOf(pHowToDismiss) = 'string') and not (pHowToDismiss = 'ALL')
  2608.         begin
  2609.             theButton := pHowToDismiss;
  2610.             pHowToDismiss := 9;
  2611.         end;
  2612.         
  2613.         Switch pHowToDismiss
  2614.         begin
  2615.             case 1:
  2616.             begin
  2617.                 KeyEq('.');
  2618.                 if not (FindWindow(SpecifiedDialog, true))
  2619.                     return(1);
  2620.             end;
  2621.             case 2:
  2622.             begin
  2623.                 SpecialKey(escapeKey, "Escape Key");
  2624.                 if not (FindWindow(SpecifiedDialog, true))
  2625.                     return(1);
  2626.             end;
  2627.             case 3:
  2628.             begin
  2629.                 if(_matchBoolean ([button t:cancelString]))
  2630.                 begin
  2631.                     SelectButton(cancelString);
  2632.                     if not (FindWindow(SpecifiedDialog, true))
  2633.                         return(1);
  2634.                 end;
  2635.             end;
  2636.             case 4:
  2637.             begin
  2638.                 if(_matchBoolean ([button t:noString]))
  2639.                 begin
  2640.                     SelectButton(noString);
  2641.                     if not (FindWindow(SpecifiedDialog, true))
  2642.                         return(1);
  2643.                 end;
  2644.             end;
  2645.             case 5:
  2646.             begin
  2647.                 if (gDontSaveString)
  2648.                     IsDontSaveBtn  := _matchBoolean ([button t:gDontSaveString w:[window o:1]]!);
  2649.                 else
  2650.                     IsDontSaveBtn  := _matchBoolean ([button t:/Don?t Save/  w:[window o:1]]!);
  2651.                 if (IsDontSaveBtn)
  2652.                 begin
  2653.                     if (gDontSaveString)
  2654.                         IsDontSaveBtn  := _match ([button t:gDontSaveString  w:[window o:1]]!,1);
  2655.                     else
  2656.                         IsDontSaveBtn  := _match ([button t:/Don?t Save/  w:[window o:1]]!,1);
  2657.                     DontSaveBtn := IsDontSaveBtn.t;
  2658.                     SelectButton(DontSaveBtn);
  2659.                     if not (FindWindow(SpecifiedDialog, true))
  2660.                         return(1);
  2661.                 end;
  2662.             end;
  2663.             case 6:
  2664.             begin
  2665.                 if(_matchBoolean ([button t:okString]))
  2666.                 begin
  2667.                     SelectButton(okString);
  2668.                     if not (FindWindow(SpecifiedDialog, true))
  2669.                         return(1);
  2670.                 end;
  2671.             end;
  2672.             case 7:
  2673.             begin
  2674.                 if(_matchBoolean ([button t:quitString]))
  2675.                 begin
  2676.                     SelectButton(quitString);
  2677.                     if not (FindWindow(SpecifiedDialog, true))
  2678.                         return(1);
  2679.                 end;
  2680.             end;
  2681.             case 8:
  2682.             begin
  2683.                 SpecialKey(returnKey, "return Key");
  2684.                 if not (FindWindow(SpecifiedDialog, true))
  2685.                     return(1);
  2686.             end;
  2687.             case 9:
  2688.             begin
  2689.                 if(_matchBoolean ([button t:theButton]))
  2690.                     SelectButton(theButton);
  2691.                 if not (FindWindow(SpecifiedDialog, true))
  2692.                     return(1);
  2693.             end;
  2694.             case 'ALL':
  2695.             begin
  2696.                 for i := 1 to 8
  2697.                 begin
  2698.                     theReturn := DialogDismisser(i,,SpecifiedDialog);
  2699.                     if(theReturn)
  2700.                         return(theReturn);
  2701.                 end;
  2702.             end;
  2703.             default:
  2704.                 LogStr("Sorry, Can't seem to dismiss the dialog");
  2705.         end;
  2706.     end;
  2707.     else
  2708.         returnVal := 1;
  2709.     Return(returnVal);
  2710. end; # DialogDismisser()
  2711.  
  2712.  
  2713.  
  2714. #########################################################################
  2715. #                     DismissDialog(pHowToDismiss, pSpecifier)
  2716. #=======================================================================
  2717. # Author:              ML
  2718. # Description:        Generic dialog dismisser.
  2719. # Assumptions:        Window is style dialog and ordinality 1.
  2720. # Parameters:        pHowToDismiss -    1    type return key
  2721. #                                {string} select button named {string}        
  2722. # Returns:            0 - dialog not dismissed
  2723. #                    1 - dialog sucessfully dismissed
  2724. # Example:            DismissDialog ('Cancel')
  2725. #=======================================================================
  2726. # History:
  2727. # KTA    7/6/93    Added default value for the pHowToDismiss input parameter
  2728. # KTA    7/7/93    Changed check to see if it actually dismissed the right dialog
  2729. # KTA    7/19/93    changed pSpecifier so descriptor is not contained in a list
  2730. # KTA    9/13/93    Added support for KeyEq('.') & better check to verfiy dialog 
  2731. #                was dismissed.
  2732. # ML    11/22/94 Added error handling support
  2733. # JC    2/6/96      Changed all window .r (Rect) traits to .b (bound) traits.
  2734. #########################################################################
  2735. TASK DismissDialog (pHowToDismiss := 1, pSpecifier := [window o:1 c:false]!)
  2736. begin    
  2737.     returnval:=0;
  2738.     SpecifiedDialog:= FindWindow( pSpecifier);
  2739.     if not (SpecifiedDialog)
  2740.         SpecifiedDialog := FindWindow([window o:1 s:dialog]);    # GenericDialog
  2741.  
  2742.     if (SpecifiedDialog)
  2743.     begin
  2744.         if (pHowToDismiss = 1)
  2745.             SpecialKey(returnKey , "Return Key");
  2746.         else if (TypeOf(pHowToDismiss) = 'string')
  2747.         begin
  2748.             if (pHowToDismiss = '.')
  2749.                 keyEq('.');
  2750.             else
  2751.                 selectbutton (pHowToDismiss);
  2752.         end;
  2753.         
  2754.         wait(2);        ## Give Dialog time to disappear    
  2755.         ## Check to see if dialog is still present
  2756.         
  2757.         if not (_matchBoolean ([window t:SpecifiedDialog.t b:SpecifiedDialog.b c:SpecifiedDialog.c g:SpecifiedDialog.g z:SpecifiedDialog.z]!))
  2758.         begin
  2759.             logstr('Dismissed dialog');
  2760.             returnval:=1;
  2761.         end;
  2762.         else
  2763.             logstr('Unable to dismiss dialog');
  2764.     end; # if SpecifiedDialog
  2765.     else
  2766.     begin
  2767.         logstr ('No dialog to dismiss');
  2768.         returnval:=1;        # Since there is no dialog to dismiss we were successful
  2769.     end;
  2770.     return(returnVal);
  2771. end; # DismissDialog()
  2772.  
  2773.  
  2774.  
  2775. #=======================================================================
  2776. # Mouse action related tasks:
  2777. #=======================================================================
  2778.  
  2779.  
  2780. #########################################################################
  2781. # MoveRelativeToWindow(pHorizontalPixels, pVerticalPixels, pSpecifier,pMouseDown,pInset)
  2782. #========================================================================
  2783. # Author:        NJV
  2784. # Description:    This routine will calculate the window's rectangle
  2785. #                and add pHorizontalPixels and pVerticalPixels input parameters  
  2786. #                to the rectangle's top-left coordinate point.  It will then
  2787. #                move the mouse to that location.  The window is
  2788. #                specified by the pSpecifier input parameter.  If the
  2789. #                pSpecifier parameter is not present, the default
  2790. #                behavior will move relative to the frontmost document window.
  2791. # Parameters:    pHorizontalPixels - int representing left (pHorizontalPixels) coord 
  2792. #                    or List of points.
  2793. #                pVerticalPixels - int representing top (pVerticalPixels) coord
  2794. #                pSpecifier - holds title or ordinality of window
  2795. #                            0 matches first s:document c:true g:true window
  2796. #                pMouseDown - (see MoveMouse())
  2797. #                pInset    -   inset from window rect for GetXYRandom
  2798. #                WhichCorner - Relative to which corner of the window
  2799. #                            1 - Top/Left
  2800. #                            2 - Bottom/Left
  2801. # Returns:        Nothing
  2802. # Examples:        MoveRelativeToWindow(12,25);
  2803. # Assumptions:    Assumes there is a window on the screen 
  2804. #========================================================================
  2805. # History:
  2806. # KTA    7/6/93        Performance support: Call (gBeginTimer);
  2807. # KTA    7/6/93        Move Performance Support into MoveMouse()
  2808. # JC    2/7/96      Changed all window .r (Rect) traits to .b (bound) traits.
  2809. #########################################################################
  2810. TASK MoveRelativeToWindow(pHorizontalPixels:= 'random', pVerticalPixels:= 'random', pSpecifier:=0,pMouseDown:=0,pInset:= {30,30,30,30}, WhichCorner := 1)
  2811. begin
  2812.     returnVal := 0;                # Init error condition
  2813.     if ( pHorizontalPixels='random') begin    # user wants random mouse move
  2814.         xyRandom := GetRandomPointsRelativeToWindow(pInset, pSpecifier);
  2815.         pHorizontalPixels := xyRandom[1];
  2816.         pVerticalPixels := xyRandom[2];
  2817.         returnVal := xyRandom;
  2818.     end;
  2819.     theWind := FindWindow(pSpecifier);
  2820.     if theWind 
  2821.     begin
  2822.         lvWindRect := theWind.b;
  2823.         if(whichCorner = 1)                    # Top/Left Corner
  2824.         begin
  2825.             lvX := lvWindRect[1];            
  2826.             lvY := lvWindRect[2];
  2827.         end;
  2828.         else if(whichCorner = 2)            # Bottom/Left
  2829.         begin
  2830.             lvX := lvWindRect[1];            
  2831.             lvY := lvWindRect[4];
  2832.         end;
  2833.         else if(whichCorner = 3)            # Bottom/Right
  2834.         begin
  2835.             lvX := lvWindRect[3];            
  2836.             lvY := lvWindRect[4];
  2837.         end;
  2838.         else if(whichCorner = 4)            # Top/Right
  2839.         begin
  2840.             lvX := lvWindRect[3];            
  2841.             lvY := lvWindRect[2];
  2842.         end;
  2843.         # Handle PointList
  2844.         if (typeOF(pHorizontalPixels) = "list")            # Need to move to a list of coordinates
  2845.         begin
  2846.             MoveMouse(pHorizontalPixels,{lvX,lvY},1,pMouseDown);    # move to the calculated location
  2847.             returnVal := {lvX,lvY};
  2848.         end;
  2849.         else
  2850.         begin
  2851.             lvFinalLeft := pHorizontalPixels + lvX;            # calculate absolutely pHorizontalPixels
  2852.             lvFinalTop := pVerticalPixels + lvY;            # calculate absolutely pVerticalPixels
  2853.             MoveMouse(lvFinalLeft,lvFinalTop,1,pMouseDown);    # move to the calculated location
  2854.             returnVal := {lvFinalLeft,lvFinalTop};
  2855.         end;
  2856.     end;
  2857.     return (returnVal);
  2858. end; # MoveRelativeToWindow()
  2859.  
  2860. #########################################################################
  2861. #                 MoveMouse(pHorizontalPixels, pVerticalPixels, pAbsolutely, pMouseDown)
  2862. #========================================================================
  2863. # Author:        DMM
  2864. # Description:    This routine will move the mouse pHorizontalPixels,pVerticalPixels
  2865. #                relative to its current location  If pHorizontalPixels and 
  2866. #                pVerticalPixels are absent or equal to "random", a random move is generated.
  2867. # Parameters:    pAbsolutely - 1 if move pAbsolutely, 0 if relative
  2868. #                pHorizontalPixels - horizontal distance in pixels to move mouse 
  2869. #                pVerticalPixels - vertical distance in pixels to move mouse
  2870. #                                if pHorizontalPixels and pVerticalPixels are absent
  2871. #                                or := "random" then a random move is generated.
  2872. #                pAbsolutely    -    1 to move to absolute location
  2873. #                                0 to move relative to current location
  2874. #                pMouseDown - 0 - don't hold mouse key down while moving
  2875. #                            1 - press mouse key down - move - release (can be a list of 1 element)
  2876. #                            2 - Click after moving - no mouse down during move
  2877. #                            3 - press mouse key down - move - don't release
  2878. #pHorizontalPixels is List    3 - MultiDrag (pressmouse-move-move-move-releaseMouse)
  2879. #                            4 - move - release
  2880. #pHorizontalPixels is List    5 - MultiClick (move-click-move-click)
  2881. #pHorizontalPixels is List    6 - move-pressmouse-move-move-move-releaseMouse
  2882. # Returns:        Nothing
  2883. #========================================================================
  2884. # History:
  2885. # KTA    9/21/93    Added gPreMoveMouseHook
  2886. # KTA    3/16/94    Added pMouseDown = 6 (move-pressmouse-move-move-move-releaseMouse)
  2887. # KTA    3/16/94    Support for pMouseDown = 1 as a list of one element
  2888. # KTA    4/13/94    Variable was named wrong which prevented moveRelativetoWindow
  2889. #                when pHorizontalPixels is a pointlist
  2890. # ML    11/22/94 Added error handling support
  2891. #########################################################################
  2892. TASK MoveMouse(pHorizontalPixels := 'random', pVerticalPixels := 'random', pAbsolutely := 1, pMouseDown := 0)
  2893. begin
  2894.     if ( pHorizontalPixels='random') begin    # user wants random mouse move
  2895.         xyRandom := getXYRandom();
  2896.         pHorizontalPixels := xyRandom[1];
  2897.         pVerticalPixels := xyRandom[2];
  2898.     end;
  2899.     
  2900.     if ((pMouseDown = 1) or (pMouseDown = 3))
  2901.         _PressMouse();
  2902.     wait(1);    #
  2903.     #### To Handle PointLists  #####
  2904.     if (typeOF(pHorizontalPixels) = "list")            # Need to move to a list of coordinates
  2905.     begin
  2906.         pointList := pHorizontalPixels;
  2907.         xOffSet := 0;
  2908.         yOffSet := 0;
  2909.         if (typeOF(pVerticalPixels) = "list")                # If its relative to window
  2910.         begin                                # We pass in pVerticalPixels as the offset of the window
  2911.             xOffSet := pVerticalPixels[1];
  2912.             yOffSet := pVerticalPixels[2];
  2913.         end;
  2914.         
  2915.         counter := 0;
  2916.         for each pairPoints in pointList
  2917.         begin
  2918.             Counter := Counter +1;
  2919.             if ((pMouseDown = 6) and (Counter = 2))    #move-pressmouse-move-move-move-releaseMouse
  2920.                 _PressMouse();
  2921.  
  2922.             nuX := pairPoints[1];
  2923.             nuY := pairPoints[2];
  2924.             pHorizontalPixels := nuX + xOffSet;            # If relative to window offset
  2925.             pVerticalPixels := nuY + yOffSet;            # otherwise the offset is 0
  2926.             
  2927.             if(global gPreMoveMouseHook)
  2928.                 Call(gPreMoveMouseHook);
  2929.                 
  2930.             if (pAbsolutely)
  2931.                 _move ('a', { pHorizontalPixels, pVerticalPixels });
  2932.             else
  2933.                 _move ('r', { pHorizontalPixels, pVerticalPixels });
  2934.                 
  2935.             if (pMouseDown = 5)        # Click for Multiclick
  2936.                 _click();
  2937.         end;
  2938.         wait(1);
  2939.         if (pMouseDown = 1)    or (pMouseDown = 3)    or (pMouseDown = 6)            # Finished MultiDrag
  2940.             _releaseMouse();
  2941.     end;
  2942.     else
  2943.     begin
  2944.         if(global gPreMoveMouseHook)
  2945.             Call(gPreMoveMouseHook);
  2946.             
  2947.         if (pAbsolutely) begin
  2948.             _move ('a', { pHorizontalPixels, pVerticalPixels });
  2949.             str := "Moved the mouse to absolute location ∂({pHorizontalPixels},{pVerticalPixels}∂)";
  2950.         end;
  2951.         else begin
  2952.             _move ('r', { pHorizontalPixels, pVerticalPixels });
  2953.             str := "Moved the mouse relative ∂({pHorizontalPixels},{pVerticalPixels}∂) to previous position";
  2954.         end;
  2955.         
  2956.         wait(1);
  2957.         # release mouse if needed
  2958.         if ((pMouseDown = 1) or (pMouseDown = 4))
  2959.             _ReleaseMouse();
  2960.     
  2961.         # add mouse down to log string if needed
  2962.         if ((pMouseDown = 1) or (pMouseDown = 3) or (pMouseDown = 4))
  2963.             str := "{str} with mouse button held down";
  2964.         
  2965.         # click if needed
  2966.         if (pMouseDown = 2 ) begin
  2967.             _Click();
  2968.             str := "{str} and clicked";
  2969.         end;
  2970.         
  2971.         # log it
  2972.         LogStr(str);
  2973.     end;
  2974. end; # MoveMouse()
  2975.  
  2976.  
  2977. #=======================================================================
  2978. # Keyboard action related tasks:
  2979. #=======================================================================
  2980.  
  2981. #########################################################################
  2982. #                                TypeStr(pTheString)
  2983. #========================================================================
  2984. # Author:        KTA
  2985. # Description:    This routine will type the string that is passed in as 
  2986. #                the <pTheStringing>.
  2987. # Parameters:    pTheString - The string to be typed
  2988. # Returns:        Nothing
  2989. # Note: If gTypeStrOverRide is defined as a task reference, it will have to handle
  2990. #        all actions all of the functionality of TypeStr since it is being overriden.
  2991. #========================================================================
  2992. # History:
  2993. # KTA 12/2/93    Added gTypeStrOverRide
  2994. # ML  11/22/94 Added error handling support
  2995. # MDF 05/03/96    Added gSwitchToUSHook task reference.  This will support Intl
  2996. #                request for switching back to the "U.S." script when pTheString
  2997. #                contains precomposed doublebyte characters.
  2998. #########################################################################
  2999. TASK TypeStr(pTheString :='') 
  3000. begin
  3001.     if (global gTypeStrOverRide)
  3002.         call (gTypeStrOverRide, pTheString);
  3003.     else
  3004.     begin
  3005.         if(global gSwitchToUSHook)
  3006.             call(gSwitchToUSHook);
  3007.         _type ({pTheString});
  3008.         LogStr("Typed '{pTheString}'");
  3009.     end;
  3010. end; # TypeStr()
  3011.  
  3012.  
  3013. #########################################################################
  3014. #                        TypeList(pStringList,pSpecialKey, pTypeFinalKey)
  3015. #========================================================================
  3016. # Author:            KTA
  3017. # Description:        This routine will type each item in the {pStringList} 
  3018. #                    and the selected special key, designated by the <pSpecialKey> 
  3019. #                    input parameter, after each item. If pTypeFinalKey = 0 the 
  3020. #                    special key will be suppressed after the last item.
  3021. # Parameters:        pStringList -    list holding strings to type
  3022. #                    pSpecialKey    -    integer representing key to type after the item has
  3023. #                            been typed. 
  3024. #                        pSpecialKey := 0 Nothing
  3025. #                        pSpecialKey := 1 (ReturnKey)
  3026. #                        pSpecialKey := 2 (TabKey)
  3027. #                        pSpecialKey := 3 (EnterKey)
  3028. #                        pSpecialKey := 4 (UpArrowKey)
  3029. #                    pTypeFinalKey - 1 to type special key after last item in <pStringList>
  3030. #                            0 to disable typing of last special key
  3031. # Return Value:        None
  3032. # Examples:            TypeList({'A','list', 'of items'},2); To type each item 
  3033. #                    and then the tabKey
  3034. # Assumptions:        None 
  3035. #========================================================================
  3036. # History:
  3037. # ML    11/22/94 Added error handling support
  3038. # MDF    04/24/96 Now checks for case where pSpecialKey = 0 (bug 1321298).
  3039. # MDF    05/01/96 Added hooks gSetupTypeList and gCloseTypeList, per Intl req.
  3040. ################################################################################    
  3041. TASK TypeList(pStringList,pSpecialKey := 0, pTypeFinalKey := 0) 
  3042. begin
  3043.     theWholeList := card(pStringList);
  3044.     for numtimes := 1 to theWholeList 
  3045.     begin
  3046.         if (global gSetupTypeList)
  3047.             call (gSetupTypeList);
  3048.         if(TypeOf(pSpecialKey) = 'integer') 
  3049.         begin
  3050.             if (pSpecialKey = 0)
  3051.                 KeyList := {'',''};
  3052.             else if (pSpecialKey = 1)
  3053.                 KeyList := {ReturnKey,' and the Return Key'};
  3054.             else if (pSpecialKey = 2) 
  3055.                 KeyList := {TabKey,' and the Tab Key'};
  3056.             else if (pSpecialKey = 3)
  3057.                 KeyList := {EnterKey,' and the Enter Key'};
  3058.             else if (pSpecialKey = 4) 
  3059.                 KeyList := {UpArrowKey,' and the Up Arrow Key'};
  3060.         end;
  3061.         else 
  3062.             KeyList := {pSpecialKey,' and some Special Key???'};
  3063.         KeyName := KeyList[2];
  3064.         Item := pStringList[numtimes];
  3065.         _Type ({ Item });
  3066.         if not (numtimes = theWholeList)
  3067.         begin
  3068.             _Type ({KeyList[1]});
  3069.         end;
  3070.         else
  3071.             if(pTypeFinalKey)
  3072.                 _Type ({KeyList[1]});
  3073.             else 
  3074.                 KeyName := '';
  3075.         LogStr("Typed '{item}'{KeyName}");
  3076.     end;
  3077.     if (global gCloseTypeList)  # hook for Intl
  3078.         call (gCloseTypeList);
  3079. end; # TypeList()
  3080.  
  3081.  
  3082. #########################################################################
  3083. #                SpecialKey( pTheKey, pKeyName, pNumTimes )
  3084. #========================================================================
  3085. # Author:        KTA
  3086. # Description:    This routine will type whatever SpecialKey is entered
  3087. #                However it will only log the name of the special character 
  3088. #                if the special key name is also passed in as a String in
  3089. #                the pKeyName parameter.
  3090. # Parameters:    pTheKey - the VU key-word for the special key to be typed
  3091. #                            (i.e. ReturnKey, TabKey, EnterKey, etc.)
  3092. #                pKeyName - the string name of the special key
  3093. #                pNumTimes - number of times to type the special key (default = 1)
  3094. # Returns:        Nothing
  3095. # Examples:        SpecialKey(TabKey,"TabKey");
  3096. #========================================================================
  3097. # History:
  3098. # KTA    7/6/93    Performance support: Call (gBeginTimer);
  3099. # KTA    9/21/93 Changed gBeginTimer to gPreSpecialKeyHook
  3100. # KTA    11/18/93 Log prior to performing the action
  3101. # ML    11/22/94 Added error handling support
  3102. #########################################################################
  3103. TASK SpecialKey( pTheKey, pKeyName := "", pNumTimes := 1 ) 
  3104. begin
  3105.     StrExt :=  "";
  3106.     if (pNumTimes <> 1)
  3107.         StrExt :=  "- ({pNumTimes}) times";
  3108.  
  3109.     if (pKeyName ="")
  3110.         LogStr("Typing some special key {StrExt}");
  3111.     else
  3112.         LogStr ("Typing {pKeyName} {StrExt}");
  3113.  
  3114.     for x := 1 to pNumTimes
  3115.     begin
  3116.         if (global gPreSpecialKeyHook)
  3117.             Call (gPreSpecialKeyHook);
  3118.     
  3119.         _type ({ pTheKey });
  3120.     end;
  3121. end; # SpecialKey()